From 49982bc1ac2b3dab699cba41076a8b09955003de Mon Sep 17 00:00:00 2001 From: Demian Vladi Date: Wed, 21 Oct 2026 07:15:11 -0700 Subject: [PATCH 1/3] fix(binning)!: honour the coarse grey depth and its sign in every family The coarse grey depth now reaches every texture family, and each of its three signs (positive MATLAB-style levels, 0 no binning, negative PyRadiomics-style bins) gives defined values. - 3D GLRLM, GLSZM, GLDM and NGTDM start their own grey depth at the coarse grey depth, as 3D GLCM already did, so --coarseGrayDepth / coarse_gray_depth bins them. Their default output moves from unbinned to 64 levels. A family's own metaparameter (3glszm/greydepth=...) still overrides it. - MATLAB-style binning sends intensity 0 to level 1, the level a ROI's darkest voxels land in too, so 3D GLSZM, GLDM and GLRLM tell background from the ROI by the voxel cloud: bin_roi_3d() bins only the ROI's voxels into a zero-filled cube in RAM, sized from the box every voxel is checked against and refusing a voxel outside it, and the streamed volume gives the background level 0 out of core. Before, GLSZM and GLDM dropped the ROI's level-1 voxels and GLRLM counted the background as level-1 runs, which put 3GLRLM_RP above 1 at positive depths. - 2D GLCM builds its co-occurrence matrix at glcm/greydepth, the depth its blank-ROI check already read, instead of the common grey depth. - The whole-slide 2D GLDZM and the whole-volume 3D GLSZM reduce hand each family its own settings vector, as does the enclosing-circle reduce. The whole-volume 3D GLSZM had been ignoring 3glszm/greydepth. The 2D GLDZM and enclosing-circle swaps are consistency only: neither family, nor the vector each read before, has a metaparameter, so the values they read are the same. - PyRadiomics-style bins are IBSI's fixed bin number, floor(n (x - min) / (max - min)) + 1, and a ROI of one intensity is one bin. Dividing by the bin width put a level on a bin edge one bin low wherever that width is inexact, and a zero-width range divided 0 by 0. The unused copy in 3d_intensity.cpp is removed. - 2D and 3D NGLDM bin through the shared sign dispatch: 0 keeps the raw levels (before, every pixel was put at level 0), and a negative depth takes PyRadiomics-style bins (before, the count wrapped to about 4.3e9 levels). The positive scheme is unchanged. - 2D GLDZM skips background pixels under PyRadiomics-style binning as it already did with no binning. Before, the background formed zones of a level missing from the matrix and every feature came back 0. - The intensity histograms take abs(depth) bins, and 24 at depth 0, which used to write one element before the buffer. The HISTOGRAM output columns use the same count, so a negative depth no longer misaligns them. - Python's coarse_gray_depth accepts any 32-bit integer but -2**31 and documents what its sign selects and what a large magnitude costs; the binding is signed; ImageQuality accepts the depth but no image-quality feature reads it. set_params() and set_environment_params() accept only the object's current depth, since they do not rebuild the per-family settings; the README and docs example set gabor_f0 instead. - One parser, Nyxus::parse_grey_depth(), reads --coarseGrayDepth and every /greydepth metaparameter (glcm, 3glcm, 3gldm, 3ngtdm, 3glrlm, 3glszm): text that is no integer is refused as such, and INT_MIN or a value past the int range as out of range. The metaparameters went through parse_as_int(), which narrows a long to int unchecked, so 3glszm/greydepth=-2147483648 reached std::abs() as UB and 3glrlm/greydepth=4294967276 became -20. Tests, each failing without the fix (the 3D GLDZM pins are new coverage of a path that was already right): - the coarse grey depth reaches every family at -20, 0 and 20, and a family's metaparameter overrides it (feature settings mechanics) - 2D GLCM at glcm/greydepth=4 equals the run with both depths at 4 - 2D and 3D NGLDM at depth 0 equal their IBSI runs - 2D NGLDM, 2D GLDZM (six features), 3D NGLDM and 3D GLDZM at depth -20 against MIRP fixed_bin_number 20; 14 of the 2D fixture's 144 pixels sit on a bin edge, and the 5 at 181 are the ones a division by the bin width sends one bin low - 3D GLSZM, GLDM and GLRLM at the default depth equal the same ROI pre-binned with no binning, in RAM and out of core (ram_limit=0, which every footprint reaches), on a ROI with level-1 voxels and one with background in its box - 3D GLRLM's RP, SRE, RLNN, GLNN and LRE hold their bounds on all 13 angles at -100, -20, 0, 32, 64, 128 and 256; the grey64 regression table is regenerated - the shared binning: a zero-width range is one bin, bin_roi_3d places voxels at their box offsets, takes the box's shape whatever aux_image_cube holds, and refuses a voxel outside the box - the CLI accepts depths at every sign and refuses the rest with the reason; the parser's own range edges; all six greydepth metaparameters refuse -2147483648, 4294967276, 2147483648 and "abc" and keep their depth - Python: every sign accepted and non-integers refused, set_params refuses a different depth and round-trips get_params(), the flag equals the four 3D metaparameters, first-order statistics at 0 equal 24 bins, HISTOGRAM columns at -20, whole-volume 3D GLSZM equals segmented under 3glszm/greydepth, and glcm/greydepth joins the out-of-core GLCM invariant Vetting: each family's MIRP generator (gen_{ngldm,gldzm,ngldm3d,gldzm3d} _mirp.py) prints and checks its negative-depth table, the 2D fixture's builder shared from oracles/square12_graded.py; the registry records the 54 negative-depth rows, the no-binning point is described as such rather than as the default, and report_output.csv/.md are regenerated. BREAKING CHANGE: 3D GLRLM, GLSZM, GLDM and NGTDM now bin at the coarse grey depth, so their default output moves from unbinned raw levels to 64 MATLAB-style levels. Pass --coarseGrayDepth=0 (coarse_gray_depth=0 in Python), or set 3/greydepth=0 for one family, to get the previous unbinned output. Python's set_params() and set_environment_params() now raise ValueError for a coarse_gray_depth other than the object's current one; pass a different depth to the constructor. --- README.md | 6 +- docs/source/cmdline_and_examples.rst | 6 +- src/nyx/constants.h | 10 + src/nyx/env_features.cpp | 7 + src/nyx/env_metaparams.cpp | 64 +-- src/nyx/environment.cpp | 14 +- src/nyx/environment.h | 2 +- src/nyx/features/3d_gldm.cpp | 29 +- src/nyx/features/3d_glrlm.cpp | 15 +- src/nyx/features/3d_glrlm_nontriv.cpp | 10 +- src/nyx/features/3d_glszm.cpp | 29 +- src/nyx/features/3d_intensity.cpp | 29 +- src/nyx/features/3d_ngldm.cpp | 19 +- src/nyx/features/3d_ngldm.h | 2 +- src/nyx/features/3d_ooc_volume.h | 21 + src/nyx/features/glcm.cpp | 6 +- src/nyx/features/gldzm.cpp | 7 +- src/nyx/features/intensity.cpp | 4 +- src/nyx/features/intensity_histogram.cpp | 4 +- src/nyx/features/ngldm.cpp | 45 +- src/nyx/features/ngldm.h | 12 +- src/nyx/features/texture_feature.h | 25 +- src/nyx/helpers/helpers.h | 23 + src/nyx/output_2_buffer.cpp | 8 +- src/nyx/output_2_csv.cpp | 8 +- src/nyx/python/new_bindings_py.cpp | 7 +- src/nyx/python/nyxus/nyxus.py | 122 +++-- src/nyx/reduce_trivial_rois.cpp | 6 +- tests/python/test_2d_ooc_invariant.py | 25 +- tests/python/test_3d_glszm_mechanics.py | 48 ++ .../test_3d_texture_background_mechanics.py | 124 +++++ .../test_coarse_gray_depth_mechanics.py | 166 +++++++ tests/python/test_nyxus.py | 12 +- tests/python/test_ooc_mechanics.py | 8 +- tests/test_2d_glcm_mechanics.h | 43 ++ tests/test_2d_gldzm_mirp.h | 45 ++ tests/test_2d_ngldm_mechanics.h | 39 ++ tests/test_2d_ngldm_mirp.h | 55 +++ tests/test_3d_gldm_common.h | 6 + tests/test_3d_gldm_regression.h | 29 +- tests/test_3d_gldzm_mirp.h | 47 ++ tests/test_3d_glrlm_invariant.h | 48 ++ tests/test_3d_glrlm_pyradiomics.h | 5 +- tests/test_3d_glrlm_regression.h | 70 ++- tests/test_3d_glszm_common.h | 6 + tests/test_3d_glszm_mechanics.h | 14 +- tests/test_3d_glszm_regression.h | 25 +- tests/test_3d_ngldm_common.h | 20 +- tests/test_3d_ngldm_mechanics.h | 24 + tests/test_3d_ngldm_mirp.h | 42 ++ tests/test_all.cc | 62 ++- tests/test_feature_settings_mechanics.h | 182 +++++++ tests/test_main_nyxus.h | 22 + tests/test_texture_binning_mechanics.h | 88 ++++ tests/vetting/TOOLS.md | 3 +- .../gldm_3d_pyradiomics_vetting_report.md | 13 +- tests/vetting/audit/glrlm_3d_golden_regen.md | 19 +- .../glrlm_3d_pyradiomics_vetting_report.md | 54 +-- tests/vetting/audit/glszm_3d_golden_regen.md | 4 +- .../glszm_3d_pyradiomics_vetting_report.md | 25 +- tests/vetting/audit/scan_gldzm3d_coverage.py | 2 + tests/vetting/audit/scan_gldzm_coverage.py | 1 + tests/vetting/audit/scan_glrlm3d_coverage.py | 2 - tests/vetting/audit/scan_glszm3d_coverage.py | 4 +- tests/vetting/audit/scan_ngldm3d_coverage.py | 2 + tests/vetting/audit/scan_ngldm_coverage.py | 2 + tests/vetting/benchmarks.md | 20 + tests/vetting/check_test_names.py | 5 +- tests/vetting/config_recipes.md | 119 +++-- tests/vetting/matrix/gldm3d.md | 32 +- tests/vetting/matrix/gldzm.md | 19 +- tests/vetting/matrix/gldzm3d.md | 19 +- tests/vetting/matrix/glszm3d.md | 26 +- tests/vetting/matrix/ngldm3d.md | 24 +- tests/vetting/oracle_coverage.csv | 114 +++-- tests/vetting/oracles/gen_gldzm3d_mirp.py | 62 ++- tests/vetting/oracles/gen_gldzm_mirp.py | 114 ++++- tests/vetting/oracles/gen_ngldm3d_mirp.py | 86 +++- tests/vetting/oracles/gen_ngldm_mirp.py | 104 +++- tests/vetting/oracles/square12_graded.py | 90 ++++ tests/vetting/report_output.csv | 448 ++++++++++-------- tests/vetting/report_output.md | 8 +- 82 files changed, 2426 insertions(+), 790 deletions(-) create mode 100644 tests/python/test_3d_glszm_mechanics.py create mode 100644 tests/python/test_3d_texture_background_mechanics.py create mode 100644 tests/python/test_coarse_gray_depth_mechanics.py create mode 100644 tests/test_2d_ngldm_mechanics.h create mode 100644 tests/test_3d_glrlm_invariant.h create mode 100644 tests/test_3d_ngldm_mechanics.h create mode 100644 tests/test_texture_binning_mechanics.h create mode 100644 tests/vetting/oracles/square12_graded.py diff --git a/README.md b/README.md index c60a5bc61..ec812d65b 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ Nyxus can also be [built from source](#building-from-source) and used from the c All parameters to configure Nyxus are available to set within the constructor. These parameters can also be updated after the object is created using the `set_params` method. This method takes in keyword arguments where the key is a valid parameter in Nyxus and the value is the updated value for the parameter. For example, -to update the `coarse_gray_depth` to 256 and the `gabor_f0` parameter to 0.1, the following can be done: +to update the `gabor_f0` parameter to 0.1, the following can be done: ```python from nyxus import Nyxus @@ -271,10 +271,10 @@ nyx = Nyxus(["*ALL*"]) intensityDir = "/path/to/images/intensities/" maskDir = "/path/to/images/labels/" features = nyx.featurize_directory (intensityDir, maskDir) -nyx.set_params(coarse_gray_depth=256, gabor_f0=0.1) +nyx.set_params(gabor_f0=0.1) ``` -A list of valid parameters is included in the documentation for this method. +A list of valid parameters is included in the documentation for this method. `coarse_gray_depth` is the exception: the grey binning is fixed when the object is constructed, so `set_params` accepts only the current value and a different depth goes to the constructor. To get the values of the parameters in Nyxus, the `get_params` method is used. If no arguments are passed to this function, then a dictionary mapping all of the variable names to the respective value is returned. For example, diff --git a/docs/source/cmdline_and_examples.rst b/docs/source/cmdline_and_examples.rst index 7a318693c..980feb0d0 100644 --- a/docs/source/cmdline_and_examples.rst +++ b/docs/source/cmdline_and_examples.rst @@ -387,7 +387,7 @@ The `features` variable will now use the custom names, as shown below All parameters to configure Nyxus are available to set within the constructor. These parameters can also be updated after the object is created using the `set_params` method. This method takes in keyword arguments where the key is a valid parameter in Nyxus and the value is the updated value for the parameter. For example, -to update the `coarse_gray_depth` to 256 and the `gabor_f0` parameter to 0.1, the following can be done: +to update the `gabor_f0` parameter to 0.1, the following can be done: .. code-block:: python @@ -397,10 +397,10 @@ to update the `coarse_gray_depth` to 256 and the `gabor_f0` parameter to 0.1, th maskDir = "/path/to/images/labels/" features = nyx.featurize_directory (intensityDir, maskDir) - nyx.set_params(coarse_gray_depth=256, gabor_f0=0.1) + nyx.set_params(gabor_f0=0.1) -A list of valid parameters is included in the documentation for this method. +A list of valid parameters is included in the documentation for this method. `coarse_gray_depth` is the exception: the grey binning is fixed when the object is constructed, so `set_params` accepts only the current value and a different depth goes to the constructor. To get the values of the parameters in Nyxus, the `get_params` method is used. If no arguments are passed to this function, then a dictionary mapping all of the variable names to the respective value is returned. For example, diff --git a/src/nyx/constants.h b/src/nyx/constants.h index 3e93c4c9e..7815fa408 100644 --- a/src/nyx/constants.h +++ b/src/nyx/constants.h @@ -3,3 +3,13 @@ constexpr double DEFAULT_T_INDEX = 0.0; constexpr double DEFAULT_C_INDEX = 0.0; // default channel index for single-channel / non-OME input constexpr int DEFAULT_NUM_HISTO_BINS = 24; + +// The number of bins the intensity histograms take from a coarse grey depth. Its sign selects a +// texture binning scheme, which a histogram has no use for, so only the magnitude is a bin count; +// 0, which bins no texture family at all, leaves a histogram at its default. +constexpr int histogram_bin_count (int coarse_gray_depth) +{ + return coarse_gray_depth > 0 ? coarse_gray_depth + : coarse_gray_depth < 0 ? -coarse_gray_depth + : DEFAULT_NUM_HISTO_BINS; +} diff --git a/src/nyx/env_features.cpp b/src/nyx/env_features.cpp index db0395060..db8a2d68c 100644 --- a/src/nyx/env_features.cpp +++ b/src/nyx/env_features.cpp @@ -735,6 +735,13 @@ void Environment::compile_feature_settings() s[(int)NyxSetting::GLCM_OFFSET].ival = 1; s[(int)NyxSetting::GLCM_GREYDEPTH].ival = get_coarse_gray_depth(); s[(int)NyxSetting::GLCM_NUMANG].ival = (int)GLCMFeature::angles.size(); + // The other per-family grey depths start at the common one too, so the coarse grey depth + // bins every texture family; a family's own metaparameter ("3glrlm/greydepth=...") then + // overrides it for that family alone. + s[(int)NyxSetting::GLDM_GREYDEPTH].ival = get_coarse_gray_depth(); + s[(int)NyxSetting::GLRLM_GREYDEPTH].ival = get_coarse_gray_depth(); + s[(int)NyxSetting::GLSZM_GREYDEPTH].ival = get_coarse_gray_depth(); + s[(int)NyxSetting::NGTDM_GREYDEPTH].ival = get_coarse_gray_depth(); // NGTDM-specific default (otherwise zero-initialised). NGTDM_RADIUS=0 empties the // neighbourhood - the scan visits only the voxel of consideration and skips it - so no // voxel is recorded as having a neighbour, the matrix stays empty and every 3D NGTDM diff --git a/src/nyx/env_metaparams.cpp b/src/nyx/env_metaparams.cpp index 9c3b75658..2b334c2d6 100644 --- a/src/nyx/env_metaparams.cpp +++ b/src/nyx/env_metaparams.cpp @@ -60,6 +60,22 @@ #include "helpers/timing.h" #include "version.h" +// Parses the value of a /greydepth metaparameter with the same rule as --coarseGrayDepth: +// returns the error message, or nothing once 'n_greys' holds the depth +static std::optional parse_greydepth_metaparam (const std::string& raw, const std::string& name, int& n_greys) +{ + switch (Nyxus::parse_grey_depth (raw, n_greys)) + { + case Nyxus::GreyDepthParse::not_an_integer: + return "error: cannot parse value \"" + raw + "\" of " + name + ": expecting an integer"; + case Nyxus::GreyDepthParse::out_of_range: + return "error: value \"" + raw + "\" of " + name + " is out of range: the magnitude must be at most " + std::to_string (INT_MAX); + case Nyxus::GreyDepthParse::ok: + break; + } + return std::nullopt; +} + std::optional Environment::set_metaparam (const std::string & p_val) { // parse LHS=RHS @@ -82,12 +98,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of glcm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "glcm/greydepth", n_greys)) + return err; STNGS_GLCM_GREYDEPTH(fsett_GLCM) = n_greys; } else if (ppath[1] == "offset") @@ -111,12 +125,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of 3glcm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "3glcm/greydepth", n_greys)) + return err; STNGS_GLCM_GREYDEPTH (fsett_D3_GLCM) = n_greys; } else if (ppath[1] == "offset") @@ -159,12 +171,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of 3gldm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "3gldm/greydepth", n_greys)) + return err; STNGS_GLDM_GREYDEPTH (fsett_D3_GLDM) = n_greys; } else @@ -177,12 +187,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of 3ngtdm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "3ngtdm/greydepth", n_greys)) + return err; STNGS_NGTDM_GREYDEPTH(fsett_D3_NGTDM) = n_greys; } else @@ -206,12 +214,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of 3glrlm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "3glrlm/greydepth", n_greys)) + return err; STNGS_GLRLM_GREYDEPTH (fsett_D3_GLRLM) = n_greys; } else @@ -224,12 +230,10 @@ std::optional Environment::set_metaparam (const std::string & p_val // check feature-specific parameter name if (ppath[1] == "greydepth") { - // interpret eq_sides[1] as int + // interpret eq_sides[1] as a grey depth int n_greys; - if (Nyxus::parse_as_int(eq_sides[1], n_greys) == false) - { - return "error: cannot parse value \"" + eq_sides[1] + "\" of 3glszm/greydepth: expecting an integer"; - } + if (auto err = parse_greydepth_metaparam (eq_sides[1], "3glszm/greydepth", n_greys)) + return err; STNGS_GLSZM_GREYDEPTH(fsett_D3_GLSZM) = n_greys; } else diff --git a/src/nyx/environment.cpp b/src/nyx/environment.cpp index bec07ead4..98b4f50b3 100644 --- a/src/nyx/environment.cpp +++ b/src/nyx/environment.cpp @@ -189,7 +189,7 @@ void Environment::show_cmdline_help() << "\t\t\tDefault: 1 \n" << "\t\t" << OPT << clo_PXLDIST << "= \n" << "\t\t\tDefault: 5 \n" - << "\t\t" << OPT << clo_COARSEGRAYDEPTH << "= \n" + << "\t\t" << OPT << clo_COARSEGRAYDEPTH << "= 0 is N MATLAB-style levels, 0 is no binning, N < 0 is |N| PyRadiomics-style bins> \n" << "\t\t\tDefault: 64 \n" << "\t\t" << OPT << clo_GLCMANGLES << "= \n" << "\t\t\tDefault: 0,45,90,135 \n" @@ -665,11 +665,17 @@ bool Environment::parse_cmdline(int argc, char** argv) // parse COARSEGRAYDEPTH if (!raw_coarse_grayscale_depth.empty()) { - // string -> integer - if (sscanf(raw_coarse_grayscale_depth.c_str(), "%d", &coarse_grayscale_depth) != 1) + // string -> integer; every sign is meaningful, and the magnitude has to be an int (see parse_grey_depth) + switch (Nyxus::parse_grey_depth (raw_coarse_grayscale_depth, coarse_grayscale_depth)) { + case Nyxus::GreyDepthParse::not_an_integer: std::cerr << "Error: " << clo_COARSEGRAYDEPTH << "=" << raw_coarse_grayscale_depth << ": expecting an integer constant\n"; return false; + case Nyxus::GreyDepthParse::out_of_range: + std::cerr << "Error: " << clo_COARSEGRAYDEPTH << "=" << raw_coarse_grayscale_depth << ": out of range, the magnitude must be at most " << INT_MAX << "\n"; + return false; + case Nyxus::GreyDepthParse::ok: + break; } } @@ -930,7 +936,7 @@ int Environment::get_coarse_gray_depth() return coarse_grayscale_depth; } -void Environment::set_coarse_gray_depth(unsigned int new_depth) +void Environment::set_coarse_gray_depth(int new_depth) { coarse_grayscale_depth = new_depth; } diff --git a/src/nyx/environment.h b/src/nyx/environment.h index 63e83625d..715687f9c 100644 --- a/src/nyx/environment.h +++ b/src/nyx/environment.h @@ -140,7 +140,7 @@ class Environment: public BasicEnvironment int get_floating_point_precision(); int get_coarse_gray_depth(); - void set_coarse_gray_depth(unsigned int new_depth); + void set_coarse_gray_depth(int new_depth); // implementation of SKIPROI bool roi_is_blacklisted (const std::string& fname, int roi_label); diff --git a/src/nyx/features/3d_gldm.cpp b/src/nyx/features/3d_gldm.cpp index 837c48294..809e5716e 100644 --- a/src/nyx/features/3d_gldm.cpp +++ b/src/nyx/features/3d_gldm.cpp @@ -85,19 +85,15 @@ void D3_GLDM_feature::calculate (LR& r, const Fsettings& s) using ACluster = std::pair; // Pairs of (intensity,number_of_neighbors) std::vector Z; - // grey-bin intensities - int w = r.aux_image_cube.width(), - h = r.aux_image_cube.height(), - d = r.aux_image_cube.depth(); - - SimpleCube D; - D.allocate(w, h, d); - auto greyInfo = STNGS_GLDM_GREYDEPTH(s); // former Nyxus::theEnvironment.get_coarse_gray_depth() if (STNGS_IBSI(s)) // former Nyxus::theEnvironment.ibsi_compliance greyInfo = 0; - bin_intensities_3d (D, r.aux_image_cube, r.aux_min, r.aux_max, greyInfo); + // grey-bin the ROI's voxels; the background outside the ROI takes level 0, the level no + // dependence is counted for or against + SimpleCube D; + Nyxus::bin_roi_3d (D, r, greyInfo); + const int w = D.width(), h = D.height(), d = D.depth(); // allocate intensities matrix if (ibsi_grey_binning(greyInfo)) @@ -116,9 +112,6 @@ void D3_GLDM_feature::calculate (LR& r, const Fsettings& s) std::sort(I.begin(), I.end()); } - // zero (backround) intensity at given grey binning method - PixIntens zeroI = matlab_grey_binning(greyInfo) ? 1 : 0; - // Gather zones for (int zslice = 0; zslice < d; zslice++) { @@ -129,7 +122,7 @@ void D3_GLDM_feature::calculate (LR& r, const Fsettings& s) PixIntens pi = D.zyx (zslice, row, col); // skip background - if (pi == zeroI) + if (pi == 0) continue; // count dependencies @@ -262,14 +255,12 @@ void D3_GLDM_feature::osized_calculate(LR& r, const Fsettings& s, ImageLoader&) int greyInfo = STNGS_IBSI(s) ? 0 : STNGS_GLDM_GREYDEPTH(s); PixIntens mn = r.aux_min, mx = r.aux_max; - const PixIntens bg = TextureFeature::bin_pixel (0, mn, mx, greyInfo); - const PixIntens zeroI = matlab_grey_binning(greyInfo) ? 1 : 0; - Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, bg, 3); + // as in calculate(), the background outside the ROI takes level 0 + Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, 0, 3); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); - // --- grey levels I: the unique levels of the whole binned cube, so the background level counts - // when the bounding box has background + // --- grey levels I: the unique nonzero levels of the binned cube, which are the ROI's own PixIntens maxbin = 0; std::set uniq = vol.levels (/*with_background=*/ true, /*drop_zero=*/ true, maxbin); I.clear(); @@ -299,7 +290,7 @@ void D3_GLDM_feature::osized_calculate(LR& r, const Fsettings& s, ImageLoader&) for (int x = 0; x < W; x++) { PixIntens pi = cur[(size_t) y * W + x]; - if (pi == zeroI) + if (pi == 0) continue; int nd = 1; diff --git a/src/nyx/features/3d_glrlm.cpp b/src/nyx/features/3d_glrlm.cpp index aa7ef9bcb..e21434c51 100644 --- a/src/nyx/features/3d_glrlm.cpp +++ b/src/nyx/features/3d_glrlm.cpp @@ -5,6 +5,7 @@ #include #include #include "3d_glrlm.h" +#include "3d_ooc_volume.h" #include "../environment.h" using namespace Nyxus; @@ -135,20 +136,14 @@ void D3_GLRLM_feature::calculate (LR& r, const Fsettings& s) return; } - // grey-bin - - int w = r.aux_image_cube.width(), - h = r.aux_image_cube.height(), - d = r.aux_image_cube.depth(); - - SimpleCube G; - G.allocate (w,h,d); - auto greyInfo = STNGS_GLRLM_GREYDEPTH(s); if (STNGS_IBSI(s)) greyInfo = 0; - bin_intensities_3d (G, r.aux_image_cube, r.aux_min, r.aux_max, greyInfo); + // grey-bin the ROI's voxels; the background outside the ROI takes level 0, the level no run is + // counted at + SimpleCube G; + Nyxus::bin_roi_3d (G, r, greyInfo); // sorted intensities diff --git a/src/nyx/features/3d_glrlm_nontriv.cpp b/src/nyx/features/3d_glrlm_nontriv.cpp index 3551eccdf..b77d76f63 100644 --- a/src/nyx/features/3d_glrlm_nontriv.cpp +++ b/src/nyx/features/3d_glrlm_nontriv.cpp @@ -42,16 +42,16 @@ void D3_GLRLM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& int greyInfo = STNGS_IBSI(s) ? 0 : STNGS_GLRLM_GREYDEPTH(s); const bool ibsi = STNGS_IBSI(s); - const PixIntens bg = TextureFeature::bin_pixel (0, minI, maxI, greyInfo); // the ROI's binned cube, streamed: a cross-plane run reaches one plane back, so the window - // keeps 2 planes - Nyxus::OocBinnedVolume vol (r, [minI, maxI, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, minI, maxI, greyInfo); }, bg, 2); + // keeps 2 planes. As in calculate(), the background outside the ROI takes level 0, at which no + // run is counted. + Nyxus::OocBinnedVolume vol (r, [minI, maxI, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, minI, maxI, greyInfo); }, 0, 2); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); const size_t nvox = vol.n_voxels(); - // --- grey levels I: 1..max under no binning, else the unique levels of the whole binned cube, - // background included, minus 0. The construction follows the binning mode, ibsi_grey_binning(); + // --- grey levels I: 1..max under no binning, else the unique nonzero levels of the binned cube, + // which are the ROI's own. The construction follows the binning mode, ibsi_grey_binning(); // the row lookup below follows the IBSI flag, and the two differ at GREYDEPTH=0 without IBSI. std::vector I; if (ibsi_grey_binning (greyInfo)) diff --git a/src/nyx/features/3d_glszm.cpp b/src/nyx/features/3d_glszm.cpp index 67fd5871f..7a8c68fa4 100644 --- a/src/nyx/features/3d_glszm.cpp +++ b/src/nyx/features/3d_glszm.cpp @@ -56,13 +56,11 @@ void D3_GLSZM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& int greyInfo = STNGS_GLSZM_GREYDEPTH(s); if (STNGS_IBSI(s)) greyInfo = 0; PixIntens mn = r.aux_min, mx = r.aux_max; - const PixIntens bg = TextureFeature::bin_pixel (0, mn, mx, greyInfo); - // calculate()'s zeroI: matlab binning puts background at level 1 - const PixIntens zeroI = matlab_grey_binning (greyInfo) ? 1 : 0; // the ROI's binned cube, streamed: the connected-component pass below reaches one plane back, - // so the window keeps 2 planes - Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, bg, 2); + // so the window keeps 2 planes. As in calculate(), the background outside the ROI takes level 0, + // which grows no zone and is no grey level. + Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, 0, 2); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); // --- grey levels I. The construction follows the binning mode, ibsi_grey_binning(); the row @@ -101,7 +99,7 @@ void D3_GLSZM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& for (int x = 0; x < W; x++) { PixIntens pi = curPlane[(size_t) y * W + x]; - if (pi == zeroI) + if (pi == 0) continue; int found = -1; @@ -632,19 +630,13 @@ void D3_GLSZM_feature::calculate (LR& r, const Fsettings& s) return; } - // bin intensities - int w = r.aux_image_cube.width(), - h = r.aux_image_cube.height(), - d = r.aux_image_cube.depth(); - - SimpleCube D; - D.allocate(w, h, d); - auto greyInfo = STNGS_GLSZM_GREYDEPTH(s); // former Nyxus::theEnvironment.get_coarse_gray_depth() if (STNGS_IBSI(s)) // former Nyxus::theEnvironment.ibsi_compliance greyInfo = 0; - bin_intensities_3d (D, r.aux_image_cube, r.aux_min, r.aux_max, greyInfo); + // bin the ROI's voxels; the background outside the ROI takes level 0, the level no zone is grown from + SimpleCube D; + Nyxus::bin_roi_3d (D, r, greyInfo); // gather unique intensities std::unordered_set U; @@ -666,12 +658,9 @@ void D3_GLSZM_feature::calculate (LR& r, const Fsettings& s) std::sort(I.begin(), I.end()); } - // zero (backround) intensity at given grey binning approach - PixIntens zeroI = matlab_grey_binning (greyInfo) ? 1 : 0; - - // gather intensity zones + // gather intensity zones; level 0 is the background std::vector > Zones; - D3_GLSZM_feature::gather_size_zones (Zones, D, zeroI); + D3_GLSZM_feature::gather_size_zones (Zones, D, 0); // width of GLSZM matrix int maxZoneArea = 0; diff --git a/src/nyx/features/3d_intensity.cpp b/src/nyx/features/3d_intensity.cpp index d2f876c2a..81ae5af1e 100644 --- a/src/nyx/features/3d_intensity.cpp +++ b/src/nyx/features/3d_intensity.cpp @@ -17,31 +17,6 @@ D3_VoxelIntensityFeatures::D3_VoxelIntensityFeatures() : FeatureMethod("PixelInt provide_features ({D3_VoxelIntensityFeatures::featureset}); } -bool matlab_grey_binning (int greybinning_info) { return greybinning_info > 0; } -bool radiomics_grey_binning (int greybinning_info) { return greybinning_info < 0; } -// returns 1-based bin indices -PixIntens to_grayscale_radiomix(PixIntens x, PixIntens min__, PixIntens max__, int binCount) -{ - if (x) - { - double binW = double(max__ - min__) / double(binCount); - PixIntens y = (PixIntens)(double(x - min__) / binW + 1); - if (y > binCount) - y = binCount; // the last bin is +1 unit wider - return y; - } - else - return 0; -} - -void bin_intensities_3d (std::vector &S, const std::vector &I, PixIntens min_I_inten, PixIntens max_I_inten, int greybin_info) -{ - // radiomics binning - auto n = I.size(); - for (size_t i = 0; i < n; i++) - S[i].inten = to_grayscale_radiomix (I[i].inten, min_I_inten, max_I_inten, std::abs(greybin_info)); -} - void D3_VoxelIntensityFeatures::calculate (LR &r, const Fsettings& s, const Dataset &ds) { calculate_grey_levels (r, s, ds); @@ -198,7 +173,7 @@ void D3_VoxelIntensityFeatures::calculate_grey_levels (LR &r, const Fsettings& s return; // P10, 25, 75, 90, IQR, QCOD, RMAD, entropy, uniformity - int n_radiomicGreyBins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : STNGS_NGREYS(s); + int n_radiomicGreyBins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : histogram_bin_count (STNGS_NGREYS(s)); TrivialHistogram H; H.initialize (n_radiomicGreyBins, binned_min, binned_max, B); auto [median_, mode_, p01_, p10_, p25_, p75_, p90_, p99_, iqr_, rmad_, entropy_, uniformity_] = H.get_stats(); @@ -368,7 +343,7 @@ void D3_VoxelIntensityFeatures::osized_calculate_grey_levels (LR & r, const Fset val_EXCESS_KURTOSIS = mom.excess_kurtosis(); // P10, 25, 75, 90, IQR, QCOD, RMAD, entropy, uniformity - int n_greybins = STNGS_NGREYS(s); + int n_greybins = histogram_bin_count (STNGS_NGREYS(s)); TrivialHistogram H; H.initialize (n_greybins, r.aux_min, r.aux_max, r.raw_voxels_NT); auto [median_, mode_, p01_, p10_, p25_, p75_, p90_, p99_, iqr_, rmad_, entropy_, uniformity_] = H.get_stats(); diff --git a/src/nyx/features/3d_ngldm.cpp b/src/nyx/features/3d_ngldm.cpp index fa9fe5854..bf26daefd 100644 --- a/src/nyx/features/3d_ngldm.cpp +++ b/src/nyx/features/3d_ngldm.cpp @@ -4,6 +4,7 @@ #include #include "3d_ngldm.h" #include "3d_ooc_volume.h" +#include "texture_feature.h" #include "../environment.h" #include "../helpers/helpers.h" @@ -90,10 +91,9 @@ void D3_NGLDM_feature::clear_buffers() * @param max_inten Maximum intensity */ -void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& Nr, const std::vector& C, const AABB& aabb, /*not const*/ SimpleCube& I, const SimpleCube& roi_mask, const std::vector& U, PixIntens max_inten, int nGrays, bool ibsi) +void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& Nr, const std::vector& C, const AABB& aabb, /*not const*/ SimpleCube& I, const SimpleCube& roi_mask, const std::vector& U, PixIntens min_inten, PixIntens max_inten, int nGrays, bool ibsi) { // Temps - PixIntens range = max_inten - 0; auto xmin = aabb.get_xmin(), ymin = aabb.get_ymin(), zmin = aabb.get_zmin(); @@ -114,7 +114,7 @@ void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& PixIntens cpi = I.zyx (z, y, x); // Binned intensity - PixIntens cpi_ = Nyxus::to_grayscale (cpi, 0, range, nGrays, ibsi); // binned 'cpi' + PixIntens cpi_ = TextureFeature::ngldm_grey_level (cpi, min_inten, max_inten, nGrays, ibsi); // binned 'cpi' // Get a dense index value for sparse binned intensity cpi_ auto iter = std::find(U.begin(), U.end(), cpi_); @@ -133,7 +133,7 @@ void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& continue; PixIntens npi = I.zyx (nz, ny, nx); // neighboring voxel intensity - PixIntens npi_ = Nyxus::to_grayscale (npi, 0, range, nGrays, ibsi); // binned 'npi' + PixIntens npi_ = TextureFeature::ngldm_grey_level (npi, min_inten, max_inten, nGrays, ibsi); // binned 'npi' if (cpi_ == npi_) n_matches++; } @@ -207,12 +207,11 @@ void D3_NGLDM_feature::prepare_NGLDM_matrix_kit (SimpleMatrix& NGL auto xmin = r.aabb.get_xmin(), ymin = r.aabb.get_ymin(), zmin = r.aabb.get_zmin(); - PixIntens range = r.aux_max - 0; std::unordered_set U; for (const auto& p : r.raw_pixels_3D) { roi_mask.zyx (p.z - zmin, p.y - ymin, p.x - xmin) = 1; - U.insert (Nyxus::to_grayscale (p.inten, 0, range, n_greys, ibsi)); + U.insert (TextureFeature::ngldm_grey_level (p.inten, r.aux_min, r.aux_max, n_greys, ibsi)); } // Cast the set to vector to be able to access intensities by indices @@ -225,7 +224,7 @@ void D3_NGLDM_feature::prepare_NGLDM_matrix_kit (SimpleMatrix& NGL //==== NGLD-matrix NGLDM.allocate(maxNr, Ng); // Ng rows, maxNr columns, but we may end up having fewer informative columns after the NGLD-matrix calculation NGLDM.fill(0); - calc_ngld_matrix (NGLDM, Nr, r.raw_pixels_3D, r.aabb, I, roi_mask, grey_levels_LUT, r.aux_max, n_greys, ibsi); // sets the actual max dependency 'Nr' + calc_ngld_matrix (NGLDM, Nr, r.raw_pixels_3D, r.aabb, I, roi_mask, grey_levels_LUT, r.aux_min, r.aux_max, n_greys, ibsi); // sets the actual max dependency 'Nr' } void D3_NGLDM_feature::calc_rowwise_and_columnwise_totals( @@ -413,11 +412,11 @@ void D3_NGLDM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& const int nGrays = STNGS_NGREYS(s); const bool ibsi = STNGS_IBSI(s); - const PixIntens range = r.aux_max; // binning basis is [0, aux_max], as in calc_ngld_matrix + const PixIntens mn = r.aux_min, mx = r.aux_max; // the same binning as calc_ngld_matrix // a cell holding the fill level is otherwise indistinguishable from a ROI voxel that binned to it - const PixIntens bg = Nyxus::to_grayscale (0, 0, range, nGrays, ibsi); - Nyxus::OocBinnedVolume vol (r, [range, nGrays, ibsi](PixIntens v) { return Nyxus::to_grayscale (v, 0, range, nGrays, ibsi); }, + const PixIntens bg = TextureFeature::ngldm_grey_level (0, mn, mx, nGrays, ibsi); + Nyxus::OocBinnedVolume vol (r, [mn, mx, nGrays, ibsi](PixIntens v) { return TextureFeature::ngldm_grey_level (v, mn, mx, nGrays, ibsi); }, bg, 3, /*with_mask=*/ true); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); diff --git a/src/nyx/features/3d_ngldm.h b/src/nyx/features/3d_ngldm.h index 04a5cc32d..cc29a5240 100644 --- a/src/nyx/features/3d_ngldm.h +++ b/src/nyx/features/3d_ngldm.h @@ -55,7 +55,7 @@ class D3_NGLDM_feature : public FeatureMethod private: void clear_buffers(); - void calc_ngld_matrix (SimpleMatrix& NGLDM, int& max_dep, const std::vector& C, const AABB& aabb, SimpleCube& I, const SimpleCube& roi_mask, const std::vector& V, PixIntens max_inten, int n_greys, bool ibsi); + void calc_ngld_matrix (SimpleMatrix& NGLDM, int& max_dep, const std::vector& C, const AABB& aabb, SimpleCube& I, const SimpleCube& roi_mask, const std::vector& V, PixIntens min_inten, PixIntens max_inten, int n_greys, bool ibsi); void calc_rowwise_and_columnwise_totals(std::vector& Mg, std::vector& Mr, const SimpleMatrix& NGLDM, const int Ng, const int Nr); void calc_features(const std::vector& Mx, const std::vector& Md, SimpleMatrix& NGLDM, int Nr, const std::vector& U, unsigned int roi_area); diff --git a/src/nyx/features/3d_ooc_volume.h b/src/nyx/features/3d_ooc_volume.h index 1ee55e337..ee63c5502 100644 --- a/src/nyx/features/3d_ooc_volume.h +++ b/src/nyx/features/3d_ooc_volume.h @@ -14,6 +14,7 @@ #include #include "pixel.h" +#include "texture_feature.h" #include "../roi_cache.h" namespace Nyxus @@ -167,4 +168,24 @@ namespace Nyxus lut[v] = (int) (std::lower_bound (I.begin(), I.end(), v) - I.begin()); return lut; } + + /// @brief The in-core counterpart of OocBinnedVolume: the ROI's bounding-box cube with every ROI + /// voxel at its grey level under 'greybin_info' and every other cell at level 0, the level the + /// texture families read as background. It is written from the voxel cloud because a binned value + /// cannot mark the background: MATLAB binning sends intensity 0 to level 1, where the ROI's darkest + /// voxels land too. The cube is sized from r.aabb, the box every voxel is checked against, so a + /// voxel that passes the check has a cell. + inline void bin_roi_3d (SimpleCube& D, const LR& r, int greybin_info) + { + D.allocate ((int) r.aabb.get_width(), (int) r.aabb.get_height(), (int) r.aabb.get_z_depth()); + D.fill (0); + const auto xmin = r.aabb.get_xmin(), + ymin = r.aabb.get_ymin(), + zmin = r.aabb.get_zmin(); + for (const auto& p : r.raw_pixels_3D) + { + r.aabb.require_contains (p.x, p.y, p.z); + D.zyx (p.z - zmin, p.y - ymin, p.x - xmin) = TextureFeature::bin_pixel (p.inten, r.aux_min, r.aux_max, greybin_info); + } + } } diff --git a/src/nyx/features/glcm.cpp b/src/nyx/features/glcm.cpp index 37693f86e..d6c426406 100644 --- a/src/nyx/features/glcm.cpp +++ b/src/nyx/features/glcm.cpp @@ -351,7 +351,8 @@ void GLCMFeature::calculateCoocMatAtAngle( PixIntens grays_min_val, PixIntens grays_max_val) { - int nGreys = s[(int)NyxSetting::GREYDEPTH].ival; + // the family's own grey depth, the same one calculate() decides a blank ROI by + int nGreys = STNGS_GLCM_GREYDEPTH(s); bool ibsi = s[(int)NyxSetting::IBSI].bval; //--- grey bining --- @@ -377,9 +378,6 @@ void GLCMFeature::calculateCoocMatAtAngle( // bin intensities auto greyInfo = nGreys; - auto greyInfo_localFeature = nGreys; - if (greyInfo_localFeature != 0 && greyInfo != greyInfo_localFeature) - greyInfo = greyInfo_localFeature; if (ibsi) greyInfo = 0; bin_intensities (D, imR, grays_min_val, grays_max_val, greyInfo); diff --git a/src/nyx/features/gldzm.cpp b/src/nyx/features/gldzm.cpp index 55abe4695..6246db270 100644 --- a/src/nyx/features/gldzm.cpp +++ b/src/nyx/features/gldzm.cpp @@ -100,8 +100,11 @@ void GLDZMFeature::prepare_GLDZM_matrix_kit (SimpleMatrix& GLDZM, if (int(inten) == VISITED) continue; - // Skip 0-intensity pixels (usually out of mask pixels) - if (ibsi_grey_binning(greyInfo)) + // Skip 0-intensity pixels, the level the background outside the mask keeps under no + // binning and under PyRadiomics binning, and which is no row of the matrix. MATLAB binning + // sends 0 to level 1, so there the background is binned like a ROI pixel and its zones are + // counted at level 1. + if (ibsi_grey_binning(greyInfo) || radiomics_grey_binning(greyInfo)) if (inten == 0) continue; diff --git a/src/nyx/features/intensity.cpp b/src/nyx/features/intensity.cpp index 337949fa2..719ad8cb3 100644 --- a/src/nyx/features/intensity.cpp +++ b/src/nyx/features/intensity.cpp @@ -208,7 +208,7 @@ void PixelIntensityFeatures::calculate_grey_levels (LR& r, const Fsettings & fse return; // P10, 25, 75, 90, IQR, QCOD, RMAD, entropy, uniformity - int n_radiomicsGreyBins = STNGS_MISSING(fsett) ? DEFAULT_NUM_HISTO_BINS : STNGS_NGREYS(fsett); + int n_radiomicsGreyBins = STNGS_MISSING(fsett) ? DEFAULT_NUM_HISTO_BINS : histogram_bin_count (STNGS_NGREYS(fsett)); TrivialHistogram H; H.initialize (n_radiomicsGreyBins, r.aux_min, r.aux_max, r.raw_pixels); auto [median_, mode_, p01_, p10_, p25_, p75_, p90_, p99_, iqr_, rmad_, entropy_, uniformity_] = H.get_stats(); @@ -362,7 +362,7 @@ void PixelIntensityFeatures::osized_calculate_grey_levels (LR& r, const Fsetting return; // P10, 25, 75, 90, IQR, QCOD, RMAD, entropy, uniformity - int n_greybins = STNGS_NGREYS(stng); + int n_greybins = histogram_bin_count (STNGS_NGREYS(stng)); TrivialHistogram H; H.initialize (n_greybins, r.aux_min, r.aux_max, r.raw_pixels_NT); auto [median_, mode_, p01_, p10_, p25_, p75_, p90_, p99_, iqr_, rmad_, entropy_, uniformity_] = H.get_stats(); diff --git a/src/nyx/features/intensity_histogram.cpp b/src/nyx/features/intensity_histogram.cpp index 45c01448a..b2aa42d7b 100644 --- a/src/nyx/features/intensity_histogram.cpp +++ b/src/nyx/features/intensity_histogram.cpp @@ -308,7 +308,7 @@ void IntensityHistogramFeatures::calculate (LR& r, const Fsettings& s, const Dat return; } - int nbins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : STNGS_NGREYS(s); + int nbins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : histogram_bin_count (STNGS_NGREYS(s)); double mn = r.aux_min, mx = r.aux_max; size_t cnt = r.raw_pixels.size(); @@ -346,7 +346,7 @@ void IntensityHistogramFeatures::osized_calculate (LR& r, const Fsettings& s, co return; } - int nbins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : STNGS_NGREYS(s); + int nbins = STNGS_MISSING(s) ? DEFAULT_NUM_HISTO_BINS : histogram_bin_count (STNGS_NGREYS(s)); double mn = r.aux_min, mx = r.aux_max; size_t cnt = r.raw_pixels_NT.size(); diff --git a/src/nyx/features/ngldm.cpp b/src/nyx/features/ngldm.cpp index 515581b2e..4657dcbdf 100644 --- a/src/nyx/features/ngldm.cpp +++ b/src/nyx/features/ngldm.cpp @@ -1,5 +1,6 @@ #include #include "ngldm.h" +#include "texture_feature.h" #include "../environment.h" using namespace Nyxus; @@ -32,14 +33,13 @@ void NGLDMfeature::clear_buffers() f_DCENE = 0; } -template void NGLDMfeature::gather_unique_intensities (std::vector & V, PixelCloud & C, PixIntens max_inten, int nGrays, bool ibsi) +template void NGLDMfeature::gather_unique_intensities (std::vector & V, PixelCloud & C, PixIntens min_inten, PixIntens max_inten, int nGrays, bool ibsi) { // Find unique intensities std::unordered_set U; - PixIntens range = max_inten - 0; for (Pixel2 p : C) { - PixIntens inten_ = Nyxus::to_grayscale (p.inten, 0, range, nGrays, ibsi); + PixIntens inten_ = TextureFeature::ngldm_grey_level (p.inten, min_inten, max_inten, nGrays, ibsi); U.insert(inten_); } @@ -48,26 +48,6 @@ template void NGLDMfeature::gather_unique_intensities (std::v std::sort (V.begin(), V.end()); } -void NGLDMfeature::gather_unique_intensities2 ( - std::vector& V, - const pixData& C, - PixIntens max_inten, - int n_greys, - bool ibsi) -{ - std::unordered_set U; - PixIntens range = max_inten - 0; - for (auto p : C) - { - PixIntens inten_ = Nyxus::to_grayscale (p, 0, range, n_greys, ibsi); - U.insert(inten_); - } - - // -- Set to vector to be able to know each intensity's index - V.insert(V.end(), U.begin(), U.end()); // alt.: std::vector V (U.begin(), U.end()); - std::sort(V.begin(), V.end()); -} - /** * Calculates an NGLD-matrix. * @@ -75,7 +55,8 @@ void NGLDMfeature::gather_unique_intensities2 ( * @param Nr (output) Nr - max column index of non-zero element of NGLDM plus 1 for zero dependency * @param I Masked ROI image matrix. (Non-ROI elements are equal to zero.) * @param U Grey levels LUT - * @param max_inten Maximum intensity + * @param min_inten ROI's minimum intensity + * @param max_inten ROI's maximum intensity */ template void NGLDMfeature::calc_ngld_matrix ( @@ -84,6 +65,7 @@ template void NGLDMfeature::calc_ngld_matrix /*not const*/ Imgmatrix& I, Maskmatrix& roi_mask, const std::vector& U, + PixIntens min_inten, PixIntens max_inten, int nGrays, bool ibsi) @@ -105,9 +87,6 @@ template void NGLDMfeature::calc_ngld_matrix {-1, 1} // South-West }; - // Temps - PixIntens range = max_inten - 0; - // Reset the max dependency int max_dep = 0; @@ -123,7 +102,7 @@ template void NGLDMfeature::calc_ngld_matrix PixIntens cpi = I.yx (y,x); // Binned intensity - PixIntens cpi_ = Nyxus::to_grayscale(cpi, 0, range, nGrays, ibsi); // binned 'cpi' + PixIntens cpi_ = TextureFeature::ngldm_grey_level (cpi, min_inten, max_inten, nGrays, ibsi); // binned 'cpi' // Get a dense index value for sparse binned intensity cpi_ auto iter = std::find (U.begin(), U.end(), cpi_); @@ -141,7 +120,7 @@ template void NGLDMfeature::calc_ngld_matrix continue; PixIntens npi = I.yx(ny, nx); // neighboring pixel intensity - PixIntens npi_ = Nyxus::to_grayscale(npi, 0, range, nGrays, ibsi); // binned 'npi' + PixIntens npi_ = TextureFeature::ngldm_grey_level (npi, min_inten, max_inten, nGrays, ibsi); // binned 'npi' if (cpi_ == npi_) n_matches++; @@ -217,7 +196,7 @@ void NGLDMfeature::prepare_NGLDM_matrix_kit ( const pixData& I = r.aux_image_matrix.ReadablePixels(); //==== Unique binned intensities gathered from ROI pixels only - gather_unique_intensities (grey_levels_LUT, r.raw_pixels, r.aux_max, n_greys, ibsi); + gather_unique_intensities (grey_levels_LUT, r.raw_pixels, r.aux_min, r.aux_max, n_greys, ibsi); Ng = grey_levels_LUT.size(); int maxNr = 9; // max number of columns in the NGLDM = max dependence 8 (due to 8 neighbors) + zero @@ -233,7 +212,7 @@ void NGLDMfeature::prepare_NGLDM_matrix_kit ( //==== NGLD-matrix NGLDM.allocate (maxNr, Ng); // Ng rows, maxNr columns, but we may end up having fewer informative columns after the NGLD-matrix calculation NGLDM.fill(0); - calc_ngld_matrix (NGLDM, Nr, I, M, grey_levels_LUT, r.aux_max, n_greys, ibsi); // sets the actual max dependency 'Nr' + calc_ngld_matrix (NGLDM, Nr, I, M, grey_levels_LUT, r.aux_min, r.aux_max, n_greys, ibsi); // sets the actual max dependency 'Nr' } void NGLDMfeature::calc_rowwise_and_columnwise_totals ( @@ -406,7 +385,7 @@ void NGLDMfeature::osized_calculate (LR& r, const Fsettings& s, ImageLoader&) //==== Unique binned intensities std::vector V; - gather_unique_intensities (V, r.raw_pixels_NT, r.aux_max, STNGS_NGREYS(s), STNGS_IBSI(s)); + gather_unique_intensities (V, r.raw_pixels_NT, r.aux_min, r.aux_max, STNGS_NGREYS(s), STNGS_IBSI(s)); //==== Image matrix WriteImageMatrix_nontriv I ("NGLDMfeature-osized_calculate-I", r.label); @@ -421,7 +400,7 @@ void NGLDMfeature::osized_calculate (LR& r, const Fsettings& s, ImageLoader&) NGLDM.allocate (maxNr, Ng); // Ng rows, Nd columns NGLDM.fill (0); int Nr = 0; - calc_ngld_matrix (NGLDM, Nr, I, M, V, r.aux_max, STNGS_NGREYS(s), STNGS_IBSI(s)); + calc_ngld_matrix (NGLDM, Nr, I, M, V, r.aux_min, r.aux_max, STNGS_NGREYS(s), STNGS_IBSI(s)); //==== Calculate vectors of totals by intensity (Sg) and by distance (Sr) std::vector Sg, Sr; diff --git a/src/nyx/features/ngldm.h b/src/nyx/features/ngldm.h index 745a559cb..4bb51b90a 100644 --- a/src/nyx/features/ngldm.h +++ b/src/nyx/features/ngldm.h @@ -59,17 +59,8 @@ class NGLDMfeature : public FeatureMethod private: void clear_buffers(); - template void gather_unique_intensities (std::vector & V, Pixelcloud& C, PixIntens max_i, int n_greys, bool ibsi); + template void gather_unique_intensities (std::vector & V, Pixelcloud& C, PixIntens min_i, PixIntens max_i, int n_greys, bool ibsi); - void gather_unique_intensities2 ( - // out - std::vector& V, - // in - const pixData& I, - PixIntens max_inten, - int n_greys, - bool ibsi); - template void calc_ngld_matrix ( //out SimpleMatrix & NGLDM, @@ -78,6 +69,7 @@ class NGLDMfeature : public FeatureMethod Imgmatrix & I, Maskmatrix& roi_mask, const std::vector & V, + PixIntens min_inten, PixIntens max_inten, int n_greys, bool ibsi); diff --git a/src/nyx/features/texture_feature.h b/src/nyx/features/texture_feature.h index a6f05f6d6..eec6c83af 100644 --- a/src/nyx/features/texture_feature.h +++ b/src/nyx/features/texture_feature.h @@ -1,5 +1,6 @@ #pragma once +#include #include "image_matrix.h" #include "image_cube.h" @@ -98,17 +99,35 @@ class TextureFeature } } + // NGLDM's grey level of intensity 'x' of a ROI spanning [min_I_inten, max_I_inten]. The sign of + // 'greybin_info' selects the kind of scheme as it does for bin_pixel(), 0 keeping the raw level and + // a negative value taking abs() PyRadiomics bins over [min, max]; IBSI keeps the raw level. A + // positive value n is NGLDM's own scheme, not bin_pixel()'s MATLAB one: Nyxus::to_grayscale() + // truncates n x / max, so [0, max] maps onto the n + 1 levels 0..n, where bin_pixel() gives 1..n. + static PixIntens ngldm_grey_level (PixIntens x, PixIntens min_I_inten, PixIntens max_I_inten, int greybin_info, bool ibsi) + { + if (ibsi || ibsi_grey_binning(greybin_info)) + return x; + if (radiomics_grey_binning(greybin_info)) + return to_grayscale_radiomix (x, min_I_inten, max_I_inten, std::abs(greybin_info)); + return Nyxus::to_grayscale (x, 0, max_I_inten, greybin_info); + } + static inline bool matlab_grey_binning (int greybinning_info) { return greybinning_info > 0; } static inline bool radiomics_grey_binning (int greybinning_info) { return greybinning_info < 0; } static inline bool ibsi_grey_binning (int greybinning_info) { return greybinning_info == 0; } - // returns 1-based bin indices + // returns 1-based bin indices: IBSI's fixed bin number, floor(n (x - min) / (max - min)) + 1. The + // product is taken before the division so that a level on a bin edge -- n (x - min) a multiple of + // (max - min), exact in double for integer levels -- lands in the bin above it, as it does in + // PyRadiomics and MIRP. A ROI of one intensity has a range of zero width, which is one bin. static inline PixIntens to_grayscale_radiomix (PixIntens x, PixIntens min__, PixIntens max__, int binCount) { if (x) { - double binW = double(max__ - min__) / double(binCount); - PixIntens y = (PixIntens) (double(x - min__) / binW + 1); + if (max__ <= min__) + return 1; + PixIntens y = (PixIntens) (std::floor (double(binCount) * double(x - min__) / double(max__ - min__)) + 1); if (y > binCount) y = binCount; // the last bin is +1 unit wider return y; diff --git a/src/nyx/helpers/helpers.h b/src/nyx/helpers/helpers.h index ab1896a36..880353530 100644 --- a/src/nyx/helpers/helpers.h +++ b/src/nyx/helpers/helpers.h @@ -1,6 +1,9 @@ #pragma once +#include #include // FLT_EPSILON +#include #include +#include #include #include #include @@ -117,6 +120,26 @@ namespace Nyxus return true; } + enum class GreyDepthParse { ok, not_an_integer, out_of_range }; + + // A grey depth as --coarseGrayDepth and every /greydepth metaparameter take it: strtol's + // syntax (optional leading whitespace and sign, then digits that must end the text), and an int + // whose magnitude is an int too, because the binning takes std::abs() of it as a level or bin + // count. INT_MIN and anything past the int range are out of range, never wrapped. + inline GreyDepthParse parse_grey_depth (const std::string& raw, int& result) + { + const char* psz = raw.c_str(); + char* endptr = nullptr; + errno = 0; + long long res = std::strtoll (psz, &endptr, 10); + if (endptr == psz || *endptr != '\0') + return GreyDepthParse::not_an_integer; + if (errno == ERANGE || res <= INT_MIN || res > INT_MAX) + return GreyDepthParse::out_of_range; + result = (int) res; + return GreyDepthParse::ok; + } + inline bool parse_as_bool (const std::string& raw, bool& result) { auto uraw = Nyxus::toupper(raw); diff --git a/src/nyx/output_2_buffer.cpp b/src/nyx/output_2_buffer.cpp index b60f79c94..cbddbd677 100644 --- a/src/nyx/output_2_buffer.cpp +++ b/src/nyx/output_2_buffer.cpp @@ -164,7 +164,7 @@ namespace Nyxus // --Intensity histogram: one column per bin (HISTOGRAM_BIN_0 .. _N-1) if (fc == (int)Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); for (int i = 0; i < nbins; i++) { std::string col = fn + "_BIN_" + std::to_string(i); @@ -296,7 +296,7 @@ namespace Nyxus // --Intensity histogram (one value per bin); pad blank ROIs to bin count if (fc == (int)Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); if ((int)vv.size() < nbins) vv.resize(nbins, 0.0); for (int i = 0; i < nbins; i++) @@ -445,7 +445,7 @@ namespace Nyxus // --Intensity histogram: one column per bin (HISTOGRAM_BIN_0 .. _N-1) if (fc == (int) Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); for (int i = 0; i < nbins; i++) { std::string col = fn + "_BIN_" + std::to_string(i); @@ -586,7 +586,7 @@ namespace Nyxus // --Intensity histogram (one value per bin); pad blank ROIs to bin count if (fc == (int) Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); if ((int)vv.size() < nbins) vv.resize(nbins, 0.0); for (int i = 0; i < nbins; i++) diff --git a/src/nyx/output_2_csv.cpp b/src/nyx/output_2_csv.cpp index d3ad09997..81907af30 100644 --- a/src/nyx/output_2_csv.cpp +++ b/src/nyx/output_2_csv.cpp @@ -194,7 +194,7 @@ namespace Nyxus // Bin edges are reconstructable from MIN/MAX and the bin count. if (fc == (int) Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); for (int i = 0; i < nbins; i++) head.emplace_back(fn + "_BIN_" + std::to_string(i)); @@ -690,7 +690,7 @@ namespace Nyxus // --Intensity histogram values (one per bin) if (fc == (int) Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); // Pad with zeros if the ROI produced no histogram (e.g. blank ROI) if ((int)vv.size() < nbins) vv.resize(nbins, 0.0); @@ -891,7 +891,7 @@ namespace Nyxus // --Intensity histogram (one value per bin); pad blank ROIs to bin count if (fc == (int)Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); if ((int)vv.size() < nbins) vv.resize(nbins, 0.0); for (int i = 0; i < nbins; i++) @@ -1055,7 +1055,7 @@ namespace Nyxus // --Intensity histogram (one value per bin); pad blank ROIs to bin count if (fc == (int) Feature2D::HISTOGRAM) { - int nbins = env.get_coarse_gray_depth(); + int nbins = histogram_bin_count (env.get_coarse_gray_depth()); if ((int)vv.size() < nbins) vv.resize(nbins, 0.0); for (int i = 0; i < nbins; i++) diff --git a/src/nyx/python/new_bindings_py.cpp b/src/nyx/python/new_bindings_py.cpp index 074f74634..b16157a15 100644 --- a/src/nyx/python/new_bindings_py.cpp +++ b/src/nyx/python/new_bindings_py.cpp @@ -78,7 +78,7 @@ void initialize_environment( const std::vector &features, int neighbor_distance, float pixels_per_micron, - uint32_t coarse_gray_depth, + int32_t coarse_gray_depth, // the sign selects the binning: > 0 MATLAB levels, 0 none, < 0 PyRadiomics bins uint32_t n_reduce_threads, int using_gpu, bool ibsi, @@ -166,7 +166,6 @@ void set_environment_params_imp ( const std::vector &features = {}, int neighbor_distance = -1, float pixels_per_micron = -1, - uint32_t coarse_gray_depth = 0, uint32_t n_reduce_threads = 0, int using_gpu = -2, float dynamic_range = -1, @@ -189,10 +188,6 @@ void set_environment_params_imp ( theEnvironment.xyRes = theEnvironment.pixelSizeUm = pixels_per_micron; } - if (coarse_gray_depth != 0) { - theEnvironment.set_coarse_gray_depth(coarse_gray_depth); - } - if (n_reduce_threads != 0) { theEnvironment.n_reduce_threads = n_reduce_threads; } diff --git a/src/nyx/python/nyxus/nyxus.py b/src/nyx/python/nyxus/nyxus.py index 5b79e1835..f4e195114 100644 --- a/src/nyx/python/nyxus/nyxus.py +++ b/src/nyx/python/nyxus/nyxus.py @@ -27,6 +27,43 @@ import pandas as pd from typing import Optional, List + +def _check_coarse_gray_depth(coarse_gray_depth): + """Refuses a coarse_gray_depth that is not a 32-bit integer whose magnitude is one too. + + The sign selects the texture binning: a positive value bins into that many MATLAB-style grey + levels, 0 bins nothing (the raw levels, as IBSI reads them), and a negative value bins into + abs(value) PyRadiomics-style bins over the ROI's range. This is a type and range check, the + same one the CLI and every /greydepth metaparameter apply; it does not judge whether + the buffers a large depth sizes fit in memory. + """ + if (isinstance(coarse_gray_depth, bool) + or not isinstance(coarse_gray_depth, (int, np.integer)) + or not -2**31 < coarse_gray_depth < 2**31): + raise ValueError( + "coarse_gray_depth must be a 32-bit integer: a positive number of MATLAB-style grey " + "levels, 0 for no binning, or a negative PyRadiomics-style bin count; got " + f"{coarse_gray_depth!r}") + + +def _without_coarse_gray_depth(nyx, params): + """Returns 'params' without coarse_gray_depth, refusing a value that differs from the object's. + + The grey depth is copied into every feature family's settings when the object is constructed, + and set_params()/set_environment_params() do not rebuild those settings, so a new value would + reach the HISTOGRAM column count but not the binning. The value the object already has changes + nothing, so it is let through, which keeps set_params(**get_params()) working. + """ + if 'coarse_gray_depth' not in params: + return params + current = nyx.get_params('coarse_gray_depth')['coarse_gray_depth'] + if params['coarse_gray_depth'] != current: + raise ValueError( + "coarse_gray_depth cannot be changed on a constructed object: pass it to the " + "constructor instead") + return {k: v for k, v in params.items() if k != 'coarse_gray_depth'} + + class Nyxus: r"""Nyxus image feature extraction library @@ -75,7 +112,14 @@ class Nyxus: Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. coarse_gray_depth: int (optional, default 64) - Custom number of levels in grayscale denoising used in texture features. + Grey binning of the texture features, selected by the sign: a positive value bins into + that many MATLAB-style levels, 0 bins nothing (the raw levels, as IBSI reads them), and a + negative value bins into abs(value) PyRadiomics-style bins over each ROI's range. Every 2D + and 3D texture family uses it unless a family's own metaparameter overrides it. The + first-order histogram statistics use abs(value) bins, or 24 at 0. Any 32-bit integer but + -2**31 is accepted, but the magnitude sizes per-ROI buffers and output columns (HISTOGRAM + writes one column per bin, 2D GLCM allocates abs(value)**2 cells), so a depth beyond the + image's dynamic range adds no information and a very large one exhausts memory. n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. use_gpu_device: int (optional, default -1) @@ -220,8 +264,7 @@ def __init__( if pixels_per_micron <= 0: raise ValueError("Pixels per micron must be greater than zero.") - if coarse_gray_depth <= 0: - raise ValueError("Custom number of grayscale levels (parameter coarse_gray_depth, default=64) must be non-negative.") + _check_coarse_gray_depth(coarse_gray_depth) if n_feature_calc_threads < 1: raise ValueError("There must be at least one feature calculation thread.") @@ -728,8 +771,9 @@ def set_environment_params (self, **params): * pixels_per_micron: float Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. - * coarse_gray_depth: int - Custom number of levels in grayscale denoising used in texture features. + * coarse_gray_depth: int + Only the object's current value is accepted: the grey binning is fixed when the + object is constructed, so a different depth goes to the constructor. * n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. * use_gpu_device: int (optional, default -1) @@ -740,11 +784,12 @@ def set_environment_params (self, **params): Maximum amount of ram to be used by Nyxus in megabytes """ + params = _without_coarse_gray_depth(self, params) + valid_params = [ 'features', 'neighbor_distance', 'pixels_per_micron', - 'coarse_gray_depth', 'n_feature_calc_threads', 'use_gpu_device', 'verbose', @@ -761,7 +806,6 @@ def set_environment_params (self, **params): features = params.get('features', []) neighbor_distance = params.get ('neighbor_distance', -1) pixels_per_micron = params.get ('pixels_per_micron', -1) - coarse_gray_depth = params.get ('coarse_gray_depth', 0) n_reduce_threads = params.get ('n_feature_calc_threads', 0) use_gpu_device = params.get ('use_gpu_device', -1) verb_lvl = params.get ('verbose', 0) @@ -774,7 +818,6 @@ def set_environment_params (self, **params): features, neighbor_distance, pixels_per_micron, - coarse_gray_depth, n_reduce_threads, use_gpu_device, dynamic_range, @@ -791,7 +834,7 @@ def set_params(self, **params): * features: List[str], * neighbor_distance * pixels_per_micron - * coarse_gray_depth + * coarse_gray_depth: only the current value; a different one goes to the constructor * n_feature_calc_threads * use_gpu_device * ibsi: bool @@ -812,7 +855,6 @@ def set_params(self, **params): "features", "neighbor_distance", "pixels_per_micron", - "coarse_gray_depth", "n_feature_calc_threads", "use_gpu_device", "ibsi", @@ -823,8 +865,11 @@ def set_params(self, **params): "verbose" ] + # before anything is applied, so a refused call changes nothing + params = _without_coarse_gray_depth(self, params) + environment_params = {} - + gabor_params = {} for key, value in params.items(): @@ -976,7 +1021,14 @@ class Nyxus3D: Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. coarse_gray_depth: int (optional, default 64) - Custom number of levels in grayscale denoising used in texture features. + Grey binning of the texture features, selected by the sign: a positive value bins into + that many MATLAB-style levels, 0 bins nothing (the raw levels, as IBSI reads them), and a + negative value bins into abs(value) PyRadiomics-style bins over each ROI's range. Every 2D + and 3D texture family uses it unless a family's own metaparameter overrides it. The + first-order histogram statistics use abs(value) bins, or 24 at 0. Any 32-bit integer but + -2**31 is accepted, but the magnitude sizes per-ROI buffers and output columns (HISTOGRAM + writes one column per bin, 2D GLCM allocates abs(value)**2 cells), so a depth beyond the + image's dynamic range adds no information and a very large one exhausts memory. n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. use_gpu_device: int (optional, default -1) @@ -1083,8 +1135,7 @@ def __init__( if pixels_per_micron <= 0: raise ValueError("Pixels per micron must be greater than zero.") - if coarse_gray_depth <= 0: - raise ValueError("Custom number of grayscale levels (parameter coarse_gray_depth, default=64) must be non-negative.") + _check_coarse_gray_depth(coarse_gray_depth) if n_feature_calc_threads < 1: raise ValueError("There must be at least one feature calculation thread.") @@ -1332,8 +1383,9 @@ def set_environment_params (self, **params): * pixels_per_micron: float Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. - * coarse_gray_depth: int - Custom number of levels in grayscale denoising used in texture features. + * coarse_gray_depth: int + Only the object's current value is accepted: the grey binning is fixed when the + object is constructed, so a different depth goes to the constructor. * n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. * use_gpu_device: int @@ -1344,11 +1396,12 @@ def set_environment_params (self, **params): Level of diagnostic output shown in the console. Set '0' to disable any diagnostic output. """ + params = _without_coarse_gray_depth(self, params) + valid_params = [ 'features', 'neighbor_distance', 'pixels_per_micron', - 'coarse_gray_depth', 'n_feature_calc_threads', 'use_gpu_device', 'verbose', @@ -1364,7 +1417,6 @@ def set_environment_params (self, **params): features = params.get('features', []) neighbor_distance = params.get ('neighbor_distance', -1) pixels_per_micron = params.get ('pixels_per_micron', -1) - coarse_gray_depth = params.get ('coarse_gray_depth', 0) n_reduce_threads = params.get ('n_feature_calc_threads', 0) use_gpu_device = params.get ('use_gpu_device', -1) verb_lvl = params.get ('verbose', 0) @@ -1377,7 +1429,6 @@ def set_environment_params (self, **params): features, neighbor_distance, pixels_per_micron, - coarse_gray_depth, n_reduce_threads, use_gpu_device, dynamic_range, @@ -1394,7 +1445,7 @@ def set_params(self, **params): * features: List[str], * neighbor_distance * pixels_per_micron - * coarse_gray_depth + * coarse_gray_depth: only the current value; a different one goes to the constructor * n_feature_calc_threads * using_gpu * ibsi: bool @@ -1408,7 +1459,6 @@ def set_params(self, **params): "features", "neighbor_distance", "pixels_per_micron", - "coarse_gray_depth", "n_feature_calc_threads", "using_gpu", "ibsi", @@ -1417,8 +1467,11 @@ def set_params(self, **params): "max_intensity" ] + # before anything is applied, so a refused call changes nothing + params = _without_coarse_gray_depth(self, params) + environment_params = {} - + gabor_params = {} @@ -1548,7 +1601,9 @@ class ImageQuality: Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. coarse_gray_depth: int (optional, default 256) - Custom number of levels in grayscale denoising used in texture features. + Accepted and validated as for Nyxus and Nyxus3D, so one set of parameters fits all three + classes, but no image-quality feature reads it: focus score, power spectrum, saturation + and sharpness are the same at every value. n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. ibsi: bool (optional, default false) @@ -1654,8 +1709,7 @@ def __init__( if pixels_per_micron <= 0: raise ValueError("Pixels per micron must be greater than zero.") - if coarse_gray_depth <= 0: - raise ValueError("Custom number of grayscale levels (parameter coarse_gray_depth, default=256) must be non-negative.") + _check_coarse_gray_depth(coarse_gray_depth) if n_feature_calc_threads < 1: raise ValueError("There must be at least one feature calculation thread.") @@ -2107,8 +2161,9 @@ def set_environment_params (self, **params): * pixels_per_micron: float Specify the image resolution in terms of pixels per micron for unit conversion of non-unitless features. - * coarse_gray_depth: int - Custom number of levels in grayscale denoising used in texture features. + * coarse_gray_depth: int + Only the object's current value is accepted: the grey binning is fixed when the + object is constructed, so a different depth goes to the constructor. * n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. * use_gpu_device: int @@ -2119,11 +2174,12 @@ def set_environment_params (self, **params): Level of diagnostic output shown in the console. Set '0' to disable any diagnostic output. """ + params = _without_coarse_gray_depth(self, params) + valid_params = [ 'features', 'neighbor_distance', 'pixels_per_micron', - 'coarse_gray_depth', 'n_feature_calc_threads', 'use_gpu_device', 'verbose', @@ -2139,7 +2195,6 @@ def set_environment_params (self, **params): features = params.get('features', []) neighbor_distance = params.get ('neighbor_distance', -1) pixels_per_micron = params.get ('pixels_per_micron', -1) - coarse_gray_depth = params.get ('coarse_gray_depth', 0) n_reduce_threads = params.get ('n_feature_calc_threads', 0) use_gpu_device = params.get ('use_gpu_device', -1) verb_lvl = params.get ('verbose', 0) @@ -2152,7 +2207,6 @@ def set_environment_params (self, **params): features, neighbor_distance, pixels_per_micron, - coarse_gray_depth, n_reduce_threads, use_gpu_device, dynamic_range, @@ -2169,7 +2223,7 @@ def set_params(self, **params): * features: List[str], * neighbor_distance * pixels_per_micron - * coarse_gray_depth + * coarse_gray_depth: only the current value; a different one goes to the constructor * n_feature_calc_threads * using_gpu * ibsi: bool @@ -2190,7 +2244,6 @@ def set_params(self, **params): "features", "neighbor_distance", "pixels_per_micron", - "coarse_gray_depth", "n_feature_calc_threads", "using_gpu", "ibsi", @@ -2200,8 +2253,11 @@ def set_params(self, **params): "verbose" ] + # before anything is applied, so a refused call changes nothing + params = _without_coarse_gray_depth(self, params) + environment_params = {} - + gabor_params = {} diff --git a/src/nyx/reduce_trivial_rois.cpp b/src/nyx/reduce_trivial_rois.cpp index 2096ad738..775037f80 100644 --- a/src/nyx/reduce_trivial_rois.cpp +++ b/src/nyx/reduce_trivial_rois.cpp @@ -548,7 +548,7 @@ namespace Nyxus //==== GLDZM if (GLDZMFeature::required(env.theFeatureSet)) { - Fsettings& s = env.fsett_D3_GLDZM; + Fsettings& s = env.fsett_GLDZM; // the 2D family's own settings, as the segmented path hands it GLDZMFeature::extract (r, s); } @@ -696,7 +696,7 @@ namespace Nyxus } if (D3_GLSZM_feature::required(env.theFeatureSet)) { - Fsettings& s = env.fsett_D3_GLDZM; + Fsettings& s = env.fsett_D3_GLSZM; // 3D GLSZM's own settings, so 3glszm/greydepth reaches the whole volume D3_GLSZM_feature::extract (r, s); } if (D3_GLRLM_feature::required(env.theFeatureSet)) @@ -852,7 +852,7 @@ namespace Nyxus if (EnclosingInscribingCircumscribingCircleFeature::required(env.theFeatureSet)) { STOPWATCH("Morphology/HexPolygEncloInsCircleGeodetLenThickness/HP/#4aaaea", "\t="); - const Fsettings & fst = env.fsett_HexagonalityPolygonality; + const Fsettings & fst = env.fsett_EnclosingInscribingCircumscribingCircle; // the circle family's own settings runParallel (EnclosingInscribingCircumscribingCircleFeature::parallel_process_1_batch, n_reduce_threads, workPerThread, jobSize, &L, &env.roiData, fst, env.dataset); } } diff --git a/tests/python/test_2d_ooc_invariant.py b/tests/python/test_2d_ooc_invariant.py index 75ed4520d..c08d9d7bd 100644 --- a/tests/python/test_2d_ooc_invariant.py +++ b/tests/python/test_2d_ooc_invariant.py @@ -180,12 +180,11 @@ def test_2d_ooc_2d_texture_matches_in_ram_invariant(tmp_path): ) -# A non-default GLCM setting: co-occurrence offset 2 against the default 1. glcm/greydepth is not -# among them because the co-occurrence matrix is binned at the common grey depth -# (calculateCoocMatAtAngle reads NyxSetting::GREYDEPTH), so it leaves every GLCM value unchanged and -# cannot show which settings vector a path was given. Metaparameters live on the instance's own -# Environment, so nothing set here reaches another instance or a later test. -GLCM_METAPARAMS = ("glcm/offset=2",) +# Non-default GLCM settings: co-occurrence offset 2 against the default 1, and 16 grey levels against +# the default 64. Both are written only to the GLCM family's own settings vector, so each shows which +# vector a path was given. Metaparameters live on the instance's own Environment, so nothing set here +# reaches another instance or a later test. +GLCM_METAPARAMS = ("glcm/offset=2", "glcm/greydepth=16") def _glcm_in_ram(tmp_path, metaparams): @@ -197,15 +196,15 @@ def _glcm_in_ram(tmp_path, metaparams): def test_2d_ooc_2d_glcm_metaparam_matches_in_ram_invariant(tmp_path): - """GLCM out-of-core must match in-RAM under a non-default glcm/offset, i.e. the oversized-ROI - path must be handed the GLCM family's own settings vector, which is where set_metaparam writes - it. At the defaults every family's vector holds the same offset, so the texture test above - cannot tell which vector the out-of-core path was given. + """GLCM out-of-core must match in-RAM under a non-default glcm/offset and glcm/greydepth, i.e. + the oversized-ROI path must be handed the GLCM family's own settings vector, which is where + set_metaparam writes them. At the defaults every family's vector holds the same values, so the + texture test above cannot tell which vector the out-of-core path was given. The fixture is a 128 px gradient spanning every one of the 64 default grey levels, so doubling - the offset moves the GLCM values. The control half asserts exactly that, per setting, so that an - out-of-core path running at the default offset cannot agree with the in-RAM one by the fixture - being insensitive to the setting.""" + the offset or binning into 16 levels moves the GLCM values. The control half asserts exactly + that, per setting, so that an out-of-core path running at the defaults cannot agree with the + in-RAM one by the fixture being insensitive to the setting.""" base = tmp_path / "default" base.mkdir() default_vals = _glcm_in_ram(base, ()) diff --git a/tests/python/test_3d_glszm_mechanics.py b/tests/python/test_3d_glszm_mechanics.py new file mode 100644 index 000000000..1bddf13e4 --- /dev/null +++ b/tests/python/test_3d_glszm_mechanics.py @@ -0,0 +1,48 @@ +"""Mechanics of the 3D GLSZM family through the Python API: which settings each workflow hands it. + +Kind: *mechanics* per tests/vetting/SPEC.md 2 -- two workflows over one volume are compared with each +other, and nothing is asserted against a reference. +""" +import os +import pathlib +import shutil + +import pytest +import nyxus + +DATA = pathlib.Path(__file__).resolve().parent.parent / "data" / "hounsfield" +INTENSITY = DATA / "ct3d_int16.nii" +WHOLE_MASK = DATA / "mask3d.nii" # label 1 in every voxel of the 8x8x8 volume + +pytestmark = pytest.mark.skipif( + not (INTENSITY.exists() and WHOLE_MASK.exists()), + reason="ct3d_int16.nii / mask3d.nii not present in tests/data/hounsfield", +) + + +def _glszm(df): + return {c: float(df[c].iloc[0]) for c in df.columns if c.startswith("3GLSZM_")} + + +# The whole-volume workflow and the segmented one hand 3D GLSZM the same settings vector, so the +# family's own grey depth reaches it on both. A segmentation covering every voxel is the same ROI as +# the whole volume, which makes the two runs comparable value for value. -8 PyRadiomics bins over the +# volume's 512 distinct levels moves every feature, so a workflow that read another family's vector +# would differ on all sixteen; the default run is the control that the two agree anyway. +@pytest.mark.parametrize("metaparam", [None, "3glszm/greydepth=-8"]) +def test_3d_glszm_whole_volume_settings_match_segmented_mechanics(tmp_path, metaparam): + shutil.copy(INTENSITY, tmp_path) + + def nyx(): + n = nyxus.Nyxus3D(["*3D_GLSZM*"]) + if metaparam: + assert n.set_metaparam(metaparam) is None + return n + + segmented = nyx().featurize_files([str(INTENSITY)], [str(WHOLE_MASK)], False) + whole = nyx().featurize_directory(str(tmp_path), None, ".*") + + seg, wv = _glszm(segmented), _glszm(whole) + assert len(seg) == 16 and seg.keys() == wv.keys() + for c in seg: + assert wv[c] == seg[c], c diff --git a/tests/python/test_3d_texture_background_mechanics.py b/tests/python/test_3d_texture_background_mechanics.py new file mode 100644 index 000000000..356537670 --- /dev/null +++ b/tests/python/test_3d_texture_background_mechanics.py @@ -0,0 +1,124 @@ +"""Mechanics of the background a 3D texture family skips: the cells of the ROI's bounding box that +are not the ROI's. + +Under MATLAB-style binning -- a positive grey depth, 64 by default -- intensity 0 bins to level 1, +the level the ROI's darkest voxels bin to as well, so the binned value cannot tell the background +from the ROI. 3D GLSZM, GLDM and GLRLM tell them apart by the ROI's voxel cloud, in RAM and out of +core, and these tests assert it. + +The reference is the same ROI with its MATLAB levels written into the image and no binning. There +the background is intensity 0 and every ROI voxel is level 1 or above, so nothing is ambiguous. A +binned run that skips a ROI voxel at level 1, or counts a background cell as one, parts from it. + +Kind: *mechanics* per tests/vetting/SPEC.md 2. Each case compares two routes to one configuration +and claims no oracle of its own. +""" +import numpy as np +import pytest + +import nyxus + +tifffile = pytest.importorskip("tifffile") + +# the in-RAM side's ram_limit; see test_ooc_mechanics.py for why it is not larger +RAM_LIMIT_LARGE_MB = 1000 + +# the out-of-core side's ram_limit: every ROI footprint is >= 0, so every ROI streams out of core +# whatever its size and whatever sizeof(Pixel2) is on the platform +RAM_LIMIT_OOC_MB = 0 + +# the default coarse grey depth, which the binned runs leave unset so that the default is what runs +DEFAULT_DEPTH = 64 + +FAMILIES = {"3GLSZM_": "*3D_GLSZM*", "3GLDM_": "*3D_GLDM*", "3GLRLM_": "*3D_GLRLM*"} + +# 8 x 90 x 90 voxels: enough for every level 1..64 to be populated on both ROIs +Z, Y, X = 8, 90, 90 + + +def _volume(): + """Intensities 1..200 over the whole volume, every one of them on many voxels.""" + z, y, x = np.meshgrid(np.arange(Z), np.arange(Y), np.arange(X), indexing="ij") + return (1 + (x * 7 + y * 13 + z * 29) % 200).astype(np.uint32) + + +def _ellipsoid(): + """A ROI that leaves background inside its bounding box.""" + z, y, x = np.meshgrid(np.arange(Z), np.arange(Y), np.arange(X), indexing="ij") + inside = (((z - (Z - 1) / 2) / (Z / 2)) ** 2 + ((y - (Y - 1) / 2) / (Y / 3)) ** 2 + + ((x - (X - 1) / 2) / (X / 3)) ** 2) <= 1.0 + return inside.astype(np.uint32) + + +def _box(): + """A ROI that fills its bounding box: the box is 1 voxel in from every face.""" + mask = np.zeros((Z, Y, X), np.uint32) + mask[1:-1, 1:-1, 1:-1] = 1 + return mask + + +def _matlab_levels(inten, mask, n): + """The MATLAB levels of the ROI's voxels, as bin_pixel_matlab() computes them: the scale runs + from 0 to the ROI's maximum, and level = floor(n x / max + 1) clipped to 1..n.""" + mx = float(inten[mask > 0].max()) + lv = np.floor((n / mx) * inten.astype(np.float64) + 1.0) + return np.clip(lv, 1, n).astype(np.uint32) + + +def _write(tmp_path, name, inten, mask): + ip, mp = tmp_path / (name + "_i.ome.tif"), tmp_path / (name + "_m.ome.tif") + tifffile.imwrite(str(ip), inten, metadata={"axes": "ZYX"}) + tifffile.imwrite(str(mp), mask, metadata={"axes": "ZYX"}) + return str(ip), str(mp) + + +def _row(groups, pair, ram_limit, **kw): + df = nyxus.Nyxus3D(groups, ram_limit=ram_limit, **kw).featurize_files([pair[0]], [pair[1]], False) + assert len(df) == 1 + return df.iloc[0] + + +def _assert_binned_equals_prebinned(tmp_path, mask): + inten = np.where(mask > 0, _volume(), 0).astype(np.uint32) + levels = _matlab_levels(inten, mask, DEFAULT_DEPTH) + prebinned = np.where(mask > 0, levels, 0).astype(np.uint32) + + # every level 1..n is populated, so the reference's levels 1..max are the binned run's levels + # and the two number their matrix rows alike + assert set(np.unique(levels[mask > 0])) == set(range(1, DEFAULT_DEPTH + 1)) + + binned = _write(tmp_path, "binned", inten, mask) + reference = _write(tmp_path, "prebinned", prebinned, mask) + groups = list(FAMILIES.values()) + + want = _row(groups, reference, RAM_LIMIT_LARGE_MB, coarse_gray_depth=0) + for side, limit in (("in RAM", RAM_LIMIT_LARGE_MB), ("out of core", RAM_LIMIT_OOC_MB)): + got = _row(groups, binned, limit) + for prefix in FAMILIES: + cols = [c for c in want.index if c.startswith(prefix)] + assert cols, prefix + bad = [(c, got[c], want[c]) for c in cols + if abs(got[c] - want[c]) > 1e-9 * max(abs(want[c]), 1.0)] + assert not bad, "%s %s: binned run parts from the prebinned one: %r" % (side, prefix, bad[:6]) + + +def _box_cells(mask): + zz, yy, xx = mask.nonzero() + return (np.ptp(zz) + 1) * (np.ptp(yy) + 1) * (np.ptp(xx) + 1) + + +# A ROI that fills its bounding box has no background to tell apart, so this isolates the ROI's own +# level-1 voxels: a family that skips level 1 as background loses them and parts from the reference. +def test_3d_texture_background_level1_voxels_kept_mechanics(tmp_path): + mask = _box() + assert _box_cells(mask) == mask.sum(), "the fixture must fill its bounding box" + _assert_binned_equals_prebinned(tmp_path, mask) + + +# The ellipsoid adds background inside its box. A family that skips only level 0 counts the box's +# corners as level-1 voxels, and one that skips level 1 loses the ROI's darkest voxels; either parts +# from the reference. +def test_3d_texture_background_by_roi_mask_mechanics(tmp_path): + mask = _ellipsoid() + assert _box_cells(mask) > mask.sum(), "the fixture must leave background inside its bounding box" + _assert_binned_equals_prebinned(tmp_path, mask) diff --git a/tests/python/test_coarse_gray_depth_mechanics.py b/tests/python/test_coarse_gray_depth_mechanics.py new file mode 100644 index 000000000..3aace0c34 --- /dev/null +++ b/tests/python/test_coarse_gray_depth_mechanics.py @@ -0,0 +1,166 @@ +"""Mechanics of coarse_gray_depth: which values the API takes, and where the value reaches. + +The sign of the coarse grey depth selects the texture binning -- a positive value bins into that many +MATLAB-style levels, 0 bins nothing, and a negative value bins into abs(value) PyRadiomics-style bins +over each ROI's range -- and every 2D and 3D texture family starts from it. The intensity histograms +take only its magnitude as a bin count, and their default of 24 bins at 0. + +Kind: *mechanics* per tests/vetting/SPEC.md 2. Each case compares two routes to one configuration, or +one configuration to its definition, and claims no oracle of its own; the oracle rows for the +binned values themselves are the families' MIRP and PyRadiomics tests. +""" +import math +import pathlib + +import numpy as np +import pytest +import nyxus + +DATA = pathlib.Path(__file__).resolve().parent.parent / "data" / "nifti" +COMPAT_INT = str(DATA / "compat_int" / "compat_int_mri.nii") +COMPAT_SEG = str(DATA / "compat_seg" / "compat_seg_liver.nii") +UT_INT = str(DATA / "phantoms" / "ut_inten.nii") +UT_SEG = str(DATA / "phantoms" / "ut_mask57.nii") + +# the 3D families that read a grey depth of their own, with the metaparameter that sets it +FAMILIES_3D = {"3GLRLM_": "3glrlm", "3GLSZM_": "3glszm", "3GLDM_": "3gldm", "3NGTDM_": "3ngtdm"} + +FIRST_ORDER = ["ENTROPY", "UNIFORMITY", "P01", "P10", "P25", "P75", "P90", "P99", "MEDIAN", + "INTERQUARTILE_RANGE", "ROBUST_MEAN_ABSOLUTE_DEVIATION"] + + +def _gradient_disk(): + """A 64x64 disk over a gradient with fixed noise: many grey levels, so every binning moves it.""" + rng = np.random.default_rng(7) + yy, xx = np.mgrid[0:64, 0:64] + img = (500 + 10 * xx + 5 * yy + rng.integers(0, 200, size=(64, 64))).astype(np.uint16) + mask = np.zeros((64, 64), dtype=np.uint16) + mask[(yy - 32) ** 2 + (xx - 32) ** 2 < 28 ** 2] = 1 + return img, mask + + +def _row_3d(nyx, intensity, segmentation, label): + df = nyx.featurize_files([intensity], [segmentation], False) + col = "ROI_label" if "ROI_label" in df.columns else "label" + return df[df[col] == label].iloc[0] + + +@pytest.mark.parametrize("depth", [-20, 0, 20]) +def test_coarse_gray_depth_every_sign_accepted_mechanics(depth): + for cls in (nyxus.Nyxus, nyxus.Nyxus3D, nyxus.ImageQuality): + nyx = cls(["*ALL*"] if cls is nyxus.Nyxus else + ["*3D_ALL*"] if cls is nyxus.Nyxus3D else ["*ALL_IMQ*"], + coarse_gray_depth=depth) + assert nyx.get_params("coarse_gray_depth")["coarse_gray_depth"] == depth + + +# The refusal path: a value that is no 32-bit integer, and the one 32-bit integer whose magnitude +# is no 32-bit integer. +@pytest.mark.parametrize("bad", [2.5, True, "64", None, -2**31, 2**31]) +def test_coarse_gray_depth_non_integer_refused_mechanics(bad): + for cls in (nyxus.Nyxus, nyxus.Nyxus3D, nyxus.ImageQuality): + with pytest.raises(ValueError, match="coarse_gray_depth must be a 32-bit integer"): + cls(["*ALL*"] if cls is nyxus.Nyxus else + ["*3D_ALL*"] if cls is nyxus.Nyxus3D else ["*ALL_IMQ*"], + coarse_gray_depth=bad) + + +# set_params() refuses a coarse grey depth other than the object's, whatever its sign, and a refused +# call applies none of its other parameters either. The depth is copied into every family's settings +# at construction and set_params() does not rebuild them, so an accepted new value would change the +# HISTOGRAM column count and nothing that is binned. +@pytest.mark.parametrize("depth", [-20, 0, 32]) +def test_coarse_gray_depth_set_params_refused_mechanics(depth): + for cls in (nyxus.Nyxus, nyxus.Nyxus3D, nyxus.ImageQuality): + nyx = cls(["*ALL*"] if cls is nyxus.Nyxus else + ["*3D_ALL*"] if cls is nyxus.Nyxus3D else ["*ALL_IMQ*"]) + before = nyx.get_params("coarse_gray_depth", "neighbor_distance") + with pytest.raises(ValueError, match="pass it to the constructor"): + nyx.set_params(coarse_gray_depth=depth, neighbor_distance=before["neighbor_distance"] + 3) + with pytest.raises(ValueError, match="pass it to the constructor"): + nyx.set_environment_params(coarse_gray_depth=depth) + assert nyx.get_params("coarse_gray_depth", "neighbor_distance") == before + + +# Negative case: the object's own depth changes nothing, so it is accepted beside the parameters +# set_params() applies, and those still reach the object. +def test_coarse_gray_depth_set_params_current_value_accepted_mechanics(): + for cls in (nyxus.Nyxus, nyxus.Nyxus3D, nyxus.ImageQuality): + nyx = cls(["*ALL*"] if cls is nyxus.Nyxus else + ["*3D_ALL*"] if cls is nyxus.Nyxus3D else ["*ALL_IMQ*"]) + p = nyx.get_params("coarse_gray_depth", "neighbor_distance") + nyx.set_params(coarse_gray_depth=p["coarse_gray_depth"], neighbor_distance=p["neighbor_distance"] + 3) + nyx.set_environment_params(coarse_gray_depth=p["coarse_gray_depth"]) + after = nyx.get_params("coarse_gray_depth", "neighbor_distance") + assert after == {"coarse_gray_depth": p["coarse_gray_depth"], + "neighbor_distance": p["neighbor_distance"] + 3} + + +# and so a Nyxus object's own get_params() goes back through set_params() unchanged +def test_coarse_gray_depth_get_params_round_trip_mechanics(): + nyx = nyxus.Nyxus(["*ALL*"], coarse_gray_depth=-20) + before = nyx.get_params() + nyx.set_params(**before) + assert nyx.get_params() == before + + +# Through the constructor, the coarse grey depth bins the four 3D families with a grey depth of their +# own exactly as each family's own metaparameter does. -20 is the configuration their PyRadiomics +# goldens are pinned at (binCount 20), so the two routes have to agree to the last bit, and on +# every feature of all four families. +@pytest.mark.skipif(not pathlib.Path(COMPAT_INT).exists(), reason="compat phantom not present") +def test_coarse_gray_depth_reaches_3d_texture_families_mechanics(): + groups = ["*3D_GLRLM*", "*3D_GLSZM*", "*3D_GLDM*", "*3D_NGTDM*"] + + by_flag = _row_3d(nyxus.Nyxus3D(groups, coarse_gray_depth=-20), COMPAT_INT, COMPAT_SEG, 1) + + per_family = nyxus.Nyxus3D(groups) + for meta in FAMILIES_3D.values(): + per_family.set_metaparam(f"{meta}/greydepth=-20") + by_metaparam = _row_3d(per_family, COMPAT_INT, COMPAT_SEG, 1) + + # and the default 64 is a different configuration, so the comparison above is not vacuous + by_default = _row_3d(nyxus.Nyxus3D(groups), COMPAT_INT, COMPAT_SEG, 1) + + for prefix in FAMILIES_3D: + cols = [c for c in by_flag.index if c.startswith(prefix)] + assert cols, prefix + for c in cols: + assert by_flag[c] == by_metaparam[c], c + assert any(by_flag[c] != by_default[c] for c in cols), prefix + + +# At 0 the intensity histograms keep their default bin count, so every statistic read off them equals +# the run at 24 bins. A 0 used as a bin count would leave the histogram one slot long and write +# before it. +def test_coarse_gray_depth_zero_first_order_2d_mechanics(): + img, mask = _gradient_disk() + at0 = nyxus.Nyxus(["*ALL_INTENSITY*"], coarse_gray_depth=0).featurize(img, mask).iloc[0] + at24 = nyxus.Nyxus(["*ALL_INTENSITY*"], coarse_gray_depth=24).featurize(img, mask).iloc[0] + for f in FIRST_ORDER: + assert math.isfinite(at0[f]), f + assert at0[f] == at24[f], f + + +@pytest.mark.skipif(not pathlib.Path(UT_INT).exists(), reason="ut_ phantom not present") +def test_coarse_gray_depth_zero_first_order_3d_mechanics(): + at0 = _row_3d(nyxus.Nyxus3D(["*3D_ALL_INTENSITY*"], coarse_gray_depth=0), UT_INT, UT_SEG, 57) + at24 = _row_3d(nyxus.Nyxus3D(["*3D_ALL_INTENSITY*"], coarse_gray_depth=24), UT_INT, UT_SEG, 57) + for f in FIRST_ORDER: + assert math.isfinite(at0["3" + f]), f + assert at0["3" + f] == at24["3" + f], f + + +# A negative depth gives the HISTOGRAM feature abs(depth) bins, and the output has one column per bin +# holding them in order: the same columns and values as the positive depth, summing to the ROI's +# pixel count. MEAN is requested beside it because HISTOGRAM on its own comes back as zeros: it belongs to +# no featureset that triggers the intensity family's calculation (PN-165; drop MEAN once that is fixed). +def test_coarse_gray_depth_negative_histogram_columns_mechanics(): + img, mask = _gradient_disk() + neg = nyxus.Nyxus(["MEAN", "HISTOGRAM"], coarse_gray_depth=-20).featurize(img, mask) + pos = nyxus.Nyxus(["MEAN", "HISTOGRAM"], coarse_gray_depth=20).featurize(img, mask) + bins = [f"HISTOGRAM_BIN_{i}" for i in range(20)] + assert [c for c in neg.columns if c.startswith("HISTOGRAM")] == bins + for c in bins: + assert neg[c].iloc[0] == pos[c].iloc[0], c + assert sum(neg[c].iloc[0] for c in bins) == int(mask.sum()) diff --git a/tests/python/test_nyxus.py b/tests/python/test_nyxus.py index c2ff69d03..ea73693d5 100644 --- a/tests/python/test_nyxus.py +++ b/tests/python/test_nyxus.py @@ -282,8 +282,8 @@ def test_set_params(self): nyx = nyxus.Nyxus (["*ALL*"]) assert nyx is not None - new_values ={'coarse_gray_depth': 512, - 'features': ['*ALL*'], + # coarse_gray_depth is constructor-only; set_params refuses it + new_values ={'features': ['*ALL*'], 'gabor_f0': 0.1, 'gabor_freqs': [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0], 'gabor_thetas': [0, 30, 60, 90, 120, 150, 180], @@ -316,10 +316,10 @@ def test_set_params(self): def test_set_single_param(self): nyx = nyxus.Nyxus (["*ALL*"]) assert nyx is not None - nyx.set_params (coarse_gray_depth = 125) + nyx.set_params (neighbor_distance = 7) actual = nyx.get_params() - expected = {'coarse_gray_depth': 125} - assert actual['coarse_gray_depth'] == expected['coarse_gray_depth'] + expected = {'neighbor_distance': 7} + assert actual['neighbor_distance'] == expected['neighbor_distance'] def test_set_environment_all(self): @@ -331,7 +331,6 @@ def test_set_environment_all(self): features = ["GABOR"], neighbor_distance = 2, pixels_per_micron = 2, - coarse_gray_depth = 2, n_feature_calc_threads = 2, dynamic_range = 1000, min_intensity = 0.1, @@ -346,7 +345,6 @@ def test_set_environment_all(self): 'features': ["GABOR"], 'neighbor_distance': 2, 'pixels_per_micron': 2, - 'coarse_gray_depth': 2, 'n_feature_calc_threads': 2 } diff --git a/tests/python/test_ooc_mechanics.py b/tests/python/test_ooc_mechanics.py index 30b49095c..c403e36e6 100644 --- a/tests/python/test_ooc_mechanics.py +++ b/tests/python/test_ooc_mechanics.py @@ -128,10 +128,10 @@ def test_ooc_3d_matches_in_ram_mechanics(tmp_path): def _make_volume_pair_partial(tmp_path): # Same intensity field as _make_volume_pair, but a non-cuboid (ellipsoid) mask that leaves - # background voxels INSIDE the ROI's bounding box. Out-of-core paths that build a grey-level - # LUT from the whole binned cube (mask + background) -- e.g. matlab binning maps the raw-0 - # background to a nonzero bin that must still appear in the LUT -- are only exercised when the - # bbox actually contains background; a whole-volume mask (hasBackground == false) never does. + # background voxels INSIDE the ROI's bounding box. How an out-of-core path tells that background + # from the ROI -- matlab binning maps the raw-0 background to level 1, a level ROI voxels carry + # too -- is only exercised when the bbox actually contains background; a whole-volume mask + # (hasBackground == false) never does. Z, Y, X = 8, 90, 90 z = np.arange(Z)[:, None, None] y = np.arange(Y)[None, :, None] diff --git a/tests/test_2d_glcm_mechanics.h b/tests/test_2d_glcm_mechanics.h index e1920627a..d8dfd9167 100644 --- a/tests/test_2d_glcm_mechanics.h +++ b/tests/test_2d_glcm_mechanics.h @@ -6,6 +6,7 @@ #include "../src/nyx/environment.h" #include "../src/nyx/feature_settings.h" #include "../src/nyx/features/glcm.h" +#include "test_2d_glcm_common.h" // the dense phantom and its settings, load_masked_test_roi_data // The production path (CLI and Python featurize) builds GLCM settings via // Environment::compile_feature_settings(), which must initialise the GLCM-specific settings @@ -27,3 +28,45 @@ inline void test_2d_glcm_bug_offset_default_is_one_mechanics() ASSERT_GT(STNGS_GLCM_GREYDEPTH(s), 0); ASSERT_GT(STNGS_GLCM_NUMANG(s), 0); } + +// 2D GLCM bins at its own grey depth, GLCM_GREYDEPTH -- what glcm/greydepth sets -- and not at the +// common GREYDEPTH the other 2D families read. Measured on the dense phantom's eight levels with +// MATLAB binning, where 4 levels merge them and 64 keep them apart: a run at GLCM_GREYDEPTH=4 under a +// common depth of 64 has to equal the run with both at 4, value for value on every feature and +// angle, and differ from the run with both at 64. +static std::vector> run_2d_glcm_dense (int greydepth, int glcm_greydepth) +{ + std::vector intensity, mask; + make_2d_glcm_dense_phantom (intensity, mask); + + Fsettings s = make_2d_glcm_dense_settings(); + s[(int)NyxSetting::IBSI].bval = false; + s[(int)NyxSetting::GREYDEPTH].ival = greydepth; + s[(int)NyxSetting::GLCM_GREYDEPTH].ival = glcm_greydepth; + + LR roidata; + GLCMFeature f; + GLCMFeature::angles = {0, 45, 90, 135}; + Nyxus::load_masked_test_roi_data (roidata, intensity.data(), mask.data(), intensity.size()); + f.calculate (roidata, s); + roidata.initialize_fvals(); + f.save_value (roidata.fvals); + return roidata.fvals; +} + +inline void test_2d_glcm_own_greydepth_bins_the_matrix_mechanics() +{ + const auto own = run_2d_glcm_dense (64, 4), + both4 = run_2d_glcm_dense (4, 4), + both64 = run_2d_glcm_dense (64, 64); + + bool any_differs = false; + for (auto fc : GLCMFeature::featureset) + { + SCOPED_TRACE ("2D feature code " + std::to_string ((int)fc)); + const auto& a = own[(int)fc]; + ASSERT_EQ (a, both4[(int)fc]); + any_differs = any_differs || a != both64[(int)fc]; + } + ASSERT_TRUE (any_differs); +} \ No newline at end of file diff --git a/tests/test_2d_gldzm_mirp.h b/tests/test_2d_gldzm_mirp.h index 7c436681a..7798be9de 100644 --- a/tests/test_2d_gldzm_mirp.h +++ b/tests/test_2d_gldzm_mirp.h @@ -206,3 +206,48 @@ void test_2d_gldzm_zde_mirp() { assert_gldzm_feature_mirp (Nyxus::Feature2D::GLDZM_ZDE, "GLDZM_ZDE"); } + +// --------------------------------------------------------------------------------------------------- +// The negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH = -20 bins the ROI into +// 20 PyRadiomics-style bins over its own [min, max], which is IBSI's fixed bin number, and MIRP is run +// with base_discretisation_method="fixed_bin_number", n_bins=20 -- each tool discretising for itself. +// Fixture bench_square12_graded (test_main_nyxus.h): 14 of its 144 pixels sit exactly on a bin edge at +// 20 bins, and the 5 at 181 are the ones a division by the bin width sends one bin low. +// +// SCOPE: the six features that read no zone's border distance. The square fills its bounding box, so +// its border distance cannot tell the 2D distance map from IBSI's (they part on ROIs with interior +// background inside the ROI), and the ten distance features are left unpinned here rather than claimed. +// +// Provenance (SPEC 6.4): tool=mirp 2.6.0, by_slice=True; +// generator=tests/vetting/oracles/gen_gldzm_mirp.py (re-verifies every pin with --check). +// Measured residual 6.2e-16 worst case; asserted at SPEC 7's exact tier, rel=1e-9. +static const ref_vals_map gldzm_2d_mirp_negdepth_ref_vals{ + { "GLDZM_GLNU", 6.645161290322581 }, // dzm_glnu_2d_fbn_n20 + { "GLDZM_GLNUN", 0.05359001040582726 }, // dzm_glnu_norm_2d_fbn_n20 + { "GLDZM_ZP", 0.8611111111111112 }, // dzm_z_perc_2d_fbn_n20 + { "GLDZM_GLV", 34.140478668054115 }, // dzm_gl_var_2d_fbn_n20 + { "GLDZM_LGLZE", 0.07338174538666452 }, // dzm_lgze_2d_fbn_n20 + { "GLDZM_HGLZE", 146.7741935483871 } // dzm_hgze_2d_fbn_n20 +}; + +void test_2d_gldzm_negative_greydepth_mirp() +{ + std::vector intensity, mask; + Nyxus::make_2d_square12_graded_phantom (intensity, mask); + + Fsettings s = make_gldzm2d_settings (false); + s[(int)NyxSetting::GREYDEPTH].ival = -20; + + LR roidata; + Nyxus::load_masked_test_roi_data (roidata, intensity.data(), mask.data(), intensity.size()); + GLDZMFeature f; + f.calculate (roidata, s); + roidata.initialize_fvals(); + f.save_value (roidata.fvals); + + for (const auto& [name, golden] : gldzm_2d_mirp_negdepth_ref_vals) + { + SCOPED_TRACE ("MIRP_ORACLE__" + name); + ASSERT_TRUE (agrees_gt (roidata.fvals[(int)Nyxus::UserFacingFeatureNames.at(name)][0], golden, 1e9)) << name; + } +} \ No newline at end of file diff --git a/tests/test_2d_ngldm_mechanics.h b/tests/test_2d_ngldm_mechanics.h new file mode 100644 index 000000000..beb89418b --- /dev/null +++ b/tests/test_2d_ngldm_mechanics.h @@ -0,0 +1,39 @@ +#pragma once + +// Mechanics of the 2D NGLDM family: what a setting does to the grey levels the matrix is built on, +// rather than the values against a reference. Claims no oracle (SPEC 2). + +// Nothing of its own: gtest, the settings recipe, NGLDMfeature and the ROI loader with its fixtures +// all arrive with the common header. +#include "test_2d_ngldm_common.h" + +static std::vector> run_2d_ngldm_square12 (int greydepth, bool ibsi) +{ + std::vector intensity, mask; + Nyxus::make_2d_square12_graded_phantom (intensity, mask); + + Fsettings s = make_ngldm2d_settings (ibsi); + s[(int)NyxSetting::GREYDEPTH].ival = greydepth; + + LR roidata; + Nyxus::load_masked_test_roi_data (roidata, intensity.data(), mask.data(), intensity.size()); + NGLDMfeature f; + f.calculate (roidata, s); + roidata.initialize_fvals(); + f.save_value (roidata.fvals); + return roidata.fvals; +} + +// A coarse grey depth of 0 bins nothing, so NGLDM reads the raw levels -- the same grey levels IBSI +// mode reads -- and every feature equals the IBSI run bit for bit. bench_square12_graded has 36 raw +// levels; a 0 that collapsed them would leave one grey level and move every feature. +void test_2d_ngldm_zero_greydepth_equals_ibsi_mechanics() +{ + const auto none = run_2d_ngldm_square12 (0, false), + ibsi = run_2d_ngldm_square12 (64, true); + for (auto fc : NGLDMfeature::featureset) + { + SCOPED_TRACE ("2D feature code " + std::to_string ((int)fc)); + ASSERT_EQ (none[(int)fc], ibsi[(int)fc]); + } +} diff --git a/tests/test_2d_ngldm_mirp.h b/tests/test_2d_ngldm_mirp.h index 36d1d30ab..fc2ed894a 100644 --- a/tests/test_2d_ngldm_mirp.h +++ b/tests/test_2d_ngldm_mirp.h @@ -74,3 +74,58 @@ void test_2d_ngldm_dcp_mirp() { assert_ngldm_feature_mirp(Nyxus::Feature2D: void test_2d_ngldm_dcv_mirp() { assert_ngldm_feature_mirp(Nyxus::Feature2D::NGLDM_DCV, "NGLDM_DCV"); } void test_2d_ngldm_dcent_mirp() { assert_ngldm_feature_mirp(Nyxus::Feature2D::NGLDM_DCENT, "NGLDM_DCENT"); } void test_2d_ngldm_dcene_mirp() { assert_ngldm_feature_mirp(Nyxus::Feature2D::NGLDM_DCENE, "NGLDM_DCENE"); } + +// --------------------------------------------------------------------------------------------------- +// The negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH = -20 bins the ROI into +// 20 PyRadiomics-style bins over its own [min, max], which is IBSI's fixed bin number, and MIRP is run +// with base_discretisation_method="fixed_bin_number", n_bins=20 -- each tool discretising for itself, +// so the binning is part of what is compared. Fixture bench_square12_graded (test_main_nyxus.h): 14 of +// its 144 pixels sit exactly on a bin edge at 20 bins, and the 5 at 181 are the ones a division by the +// bin width sends one bin low. NGLDM_DCP is left out: both tools return 1 whenever every pixel has a +// same-level neighbour. +// +// Provenance (SPEC 6.4): tool=mirp 2.6.0, by_slice=True, distance 1, difference level 0; +// generator=tests/vetting/oracles/gen_ngldm_mirp.py (re-verifies every pin with --check). +// Measured residual 2.1e-16 worst case; asserted at rel=1e-9, and at rel=1e-6 for NGLDM_DCENT, the +// family's one logarithm, whose last bits move between platforms. +static const ref_vals_map ngldm_2d_mirp_negdepth_ref_vals{ + { "NGLDM_LDE", 0.8128858024691358 }, // ngl_lde_d1_a0.0_2d_fbn_n20 + { "NGLDM_HDE", 1.9027777777777777 }, // ngl_hde_d1_a0.0_2d_fbn_n20 + { "NGLDM_LGLCE", 0.08136848819766401 }, // ngl_lgce_d1_a0.0_2d_fbn_n20 + { "NGLDM_HGLCE", 142.54861111111111 }, // ngl_hgce_d1_a0.0_2d_fbn_n20 + { "NGLDM_LDLGLE", 0.059117449770570624 }, // ngl_ldlge_d1_a0.0_2d_fbn_n20 + { "NGLDM_LDHGLE", 120.47762345679013 }, // ngl_ldhge_d1_a0.0_2d_fbn_n20 + { "NGLDM_HDLGLE", 0.20685947399060212 }, // ngl_hdlge_d1_a0.0_2d_fbn_n20 + { "NGLDM_HDHGLE", 246.60416666666666 }, // ngl_hdhge_d1_a0.0_2d_fbn_n20 + { "NGLDM_GLNU", 7.819444444444445 }, // ngl_glnu_d1_a0.0_2d_fbn_n20 + { "NGLDM_GLNUN", 0.054301697530864196 }, // ngl_glnu_norm_d1_a0.0_2d_fbn_n20 + { "NGLDM_DCNU", 88.93055555555556 }, // ngl_dcnu_d1_a0.0_2d_fbn_n20 + { "NGLDM_DCNUN", 0.6175733024691358 }, // ngl_dcnu_norm_d1_a0.0_2d_fbn_n20 + { "NGLDM_GLV", 34.475260416666664 }, // ngl_gl_var_d1_a0.0_2d_fbn_n20 + { "NGLDM_DCV", 0.27006172839506165 }, // ngl_dc_var_d1_a0.0_2d_fbn_n20 + { "NGLDM_DCENT", 4.9476106370788075 }, // ngl_dc_entr_d1_a0.0_2d_fbn_n20 + { "NGLDM_DCENE", 0.03607253086419753 } // ngl_dc_energy_d1_a0.0_2d_fbn_n20 +}; + +void test_2d_ngldm_negative_greydepth_mirp() +{ + std::vector intensity, mask; + Nyxus::make_2d_square12_graded_phantom (intensity, mask); + + Fsettings s = make_ngldm2d_settings (false); + s[(int)NyxSetting::GREYDEPTH].ival = -20; + + LR roidata; + Nyxus::load_masked_test_roi_data (roidata, intensity.data(), mask.data(), intensity.size()); + NGLDMfeature f; + f.calculate (roidata, s); + roidata.initialize_fvals(); + f.save_value (roidata.fvals); + + for (const auto& [name, golden] : ngldm_2d_mirp_negdepth_ref_vals) + { + SCOPED_TRACE ("MIRP_ORACLE__" + name); + const double frac = name == "NGLDM_DCENT" ? 1e6 : 1e9; + ASSERT_TRUE (agrees_gt (roidata.fvals[(int)Nyxus::UserFacingFeatureNames.at(name)][0], golden, frac)) << name; + } +} \ No newline at end of file diff --git a/tests/test_3d_gldm_common.h b/tests/test_3d_gldm_common.h index 2e52e5234..c39bb9483 100644 --- a/tests/test_3d_gldm_common.h +++ b/tests/test_3d_gldm_common.h @@ -149,6 +149,12 @@ static void run_3d_gldm_on_volume ( r.aux_max = v; } + // the cube is the ROI's bounding box, its corner at the origin: calculate() places the voxel + // cloud in the cube through it + r.aabb.init_x (0); r.aabb.update_x (w - 1); + r.aabb.init_y (0); r.aabb.update_y (h - 1); + r.aabb.init_z (0); r.aabb.update_z (d - 1); + ASSERT_NO_THROW(r.initialize_fvals()); ASSERT_NO_THROW(f.calculate(r, s)); f.save_value(r.fvals); diff --git a/tests/test_3d_gldm_regression.h b/tests/test_3d_gldm_regression.h index 988670eb4..0321c9148 100644 --- a/tests/test_3d_gldm_regression.h +++ b/tests/test_3d_gldm_regression.h @@ -7,12 +7,11 @@ // MATLAB-style level-count binning -- a different configuration from the PyRadiomics recipe next // door, not a second opinion on it. // -// Recipe gldm3d.regression_ut_phantom_nobinning: the same phantom and label with GLDM_GREYDEPTH=0. -// Zero is not one config among several -- it is the value a settings vector carries when nothing -// names the family's binning, i.e. what env_features.cpp's zero-fill leaves behind and what every -// run that omits --3gldm/greydepth computes. The one above cannot stand in for it: the two differ by -// three orders of magnitude on the same ROI (3GLDM_HGLE 1957.19 against 4275550.79), so a pin taken -// at 64 says nothing about what the default emits. +// Recipe gldm3d.regression_ut_phantom_nobinning: the same phantom and label with GLDM_GREYDEPTH=0 -- +// no binning, the raw levels, which --coarseGrayDepth=0 or 3gldm/greydepth=0 selects. A run that +// names neither bins at the coarse grey depth, 64, which is the recipe above. The one above cannot +// stand in for this one: the two differ by three orders of magnitude on the same ROI (3GLDM_HGLE +// 1957.19 against 4275550.79), so a pin taken at 64 says nothing about the raw-level configuration. // // Recipe gldm3d.regression_constant_roi: a synthetic nonempty ROI of one intensity at the same // GLDM_GREYDEPTH=0, reachable wherever a segmentation lands on a flat region. All fourteen come back @@ -51,9 +50,9 @@ static const ref_vals_map gldm_3d_regression_ref_vals {"3GLDM_SDLGLE", 7.4259950258209084e-05} }; -// The same fourteen at the compiled default GLDM_GREYDEPTH=0, on the same ROI. Nothing in the tree -// asserted the default configuration before this table: the family's binning is the only setting it -// reads, and every pin stood at a value only an explicit --3gldm/greydepth reaches. +// The same fourteen at GLDM_GREYDEPTH=0, no binning, on the same ROI. The family's binning is the only +// setting it reads, so this table and the one above pin its two production points: the raw levels +// and the default MATLAB-style 64. static const ref_vals_map gldm_3d_regression_nobinning_ref_vals { {"3GLDM_DE", 11.489092381392878}, @@ -127,7 +126,7 @@ static void assert_3d_gldm_feature_nobinning_regression (const Nyxus::Feature3D& auto [ipath, mpath, label] = get_3d_segmented_phantom(); // GREYDEPTH stays at the neighbouring recipe's 64 because this family never reads it, so the two // tables differ in the one setting under test and nothing else. - Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*the compiled default: no binning*/); + Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*no binning*/); std::vector> fvals; SimpleCube cube; @@ -185,7 +184,7 @@ void test_3d_gldm_sdlgle_regression() { assert_3d_gldm_feature_regression(Nyxus: void test_3d_gldm_dump_nobinning_regression() { auto [ipath, mpath, label] = get_3d_segmented_phantom(); - Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*the compiled default: no binning*/); + Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*no binning*/); std::vector> fvals; SimpleCube cube; @@ -225,12 +224,12 @@ void test_3d_gldm_sdlgle_nobinning_regression() { assert_3d_gldm_feature_nobinni // divergence rather than a convention. Run at GLDM_GREYDEPTH=0 because that is where the intercept // stands alone: a negative control restricting it to empty cubes has the arithmetic underneath // reproduce PyRadiomics to the last bit on all seven dependence-axis features, so nothing below the -// guard is wrong. At radiomics binning the same control stays green instead -- to_grayscale_radiomix() -// divides by max - min, which is zero here, so every voxel bins to background and the Nz == 0 branch -// emits the same sentinel by a second route. Cell and values: tests/vetting/matrix/gldm3d.md. +// guard is wrong. At radiomics binning to_grayscale_radiomix() puts this range of zero width into one +// bin, so below the guard every voxel is level 1 there too. Cell and values: +// tests/vetting/matrix/gldm3d.md. void test_3d_gldm_constant_roi_regression() { - Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*the compiled default: no binning*/); + Fsettings s = make_gldm3d_settings (64/*greydepth, inert here*/, 0/*no binning*/); s[(int)NyxSetting::SOFTNAN].rval = gldm_3d_regression_softnan; LR r; diff --git a/tests/test_3d_gldzm_mirp.h b/tests/test_3d_gldzm_mirp.h index f532b3613..4f0f009d3 100644 --- a/tests/test_3d_gldzm_mirp.h +++ b/tests/test_3d_gldzm_mirp.h @@ -233,3 +233,50 @@ void test_3d_gldzm_zde_radiomics_mirp() { assert_3d_gldzm_feature_mirp (Nyxus::Feature3D::GLDZM_ZDE, "3GLDZM_ZDE", make_gldzm3d_settings(-8, false)); } + +// --------------------------------------------------------------------------------------------------- +// The negative coarse grey depth at a bin count that re-bins, recipe gldzm3d.mirp_fbn20_negdepth: +// GREYDEPTH = -20 on the segmented phantom (ut_inten.nii + ut_mask57.nii, label 57), whose 2001 levels +// it folds into 20 PyRadiomics-style bins over the ROI's own [min, max] -- IBSI's fixed bin number -- +// against MIRP base_discretisation_method="fixed_bin_number", n_bins=20, each tool discretising for +// itself. gldzm3d.mirp_compat_phantom_radiomics above runs the same scheme where it is the identity; +// this is the point where it is not. MIRP is handed the integer levels Nyxus loads the float phantom +// as (the loader's shift, not a binning step). +// +// Provenance (SPEC 6.4): tool=mirp 2.6.0, by_slice=False; +// generator=tests/vetting/oracles/gen_gldzm3d_mirp.py (re-verifies every pin with --check). +// Measured residual 2.4e-16 worst case, 4.1e-15 on 3GLDZM_ZDE; asserted at rel=1e-9, and at +// rel=1e-6 for 3GLDZM_ZDE, the family's one logarithm. +static const ref_vals_map gldzm_3d_mirp_negdepth_ref_vals{ + { "3GLDZM_SDE", 0.6842603639540243 }, // dzm_sde_3d_fbn_n20 + { "3GLDZM_LDE", 3.147037956722242 }, // dzm_lde_3d_fbn_n20 + { "3GLDZM_LGLZE", 0.006184750720985788 }, // dzm_lgze_3d_fbn_n20 + { "3GLDZM_HGLZE", 247.83682156793188 }, // dzm_hgze_3d_fbn_n20 + { "3GLDZM_SDLGLE", 0.0028345794792165105 }, // dzm_sdlge_3d_fbn_n20 + { "3GLDZM_SDHGLE", 201.29563699595957 }, // dzm_sdhge_3d_fbn_n20 + { "3GLDZM_LDLGLE", 0.03740473942858066 }, // dzm_ldlge_3d_fbn_n20 + { "3GLDZM_LDHGLE", 508.3433841787868 }, // dzm_ldhge_3d_fbn_n20 + { "3GLDZM_GLNU", 482.0610145441646 }, // dzm_glnu_3d_fbn_n20 + { "3GLDZM_GLNUN", 0.08550213099399868 }, // dzm_glnu_norm_3d_fbn_n20 + { "3GLDZM_ZDNU", 2540.028024122029 }, // dzm_zdnu_3d_fbn_n20 + { "3GLDZM_ZDNUN", 0.4505193373753156 }, // dzm_zdnu_norm_3d_fbn_n20 + { "3GLDZM_ZP", 0.02054425139925373 }, // dzm_z_perc_3d_fbn_n20 + { "3GLDZM_GLV", 14.773653316112062 }, // dzm_gl_var_3d_fbn_n20 + { "3GLDZM_ZDV", 0.7135929028191487 }, // dzm_zd_var_3d_fbn_n20 + { "3GLDZM_ZDE", 4.552263594474714 } // dzm_zd_entr_3d_fbn_n20 +}; + +void test_3d_gldzm_negative_greydepth_mirp() +{ + auto [ipath, mpath, label] = get_3d_segmented_phantom(); + std::vector> fvals; + ASSERT_NO_FATAL_FAILURE (extract_3d_gldzm (fvals, ipath, mpath, label, make_gldzm3d_settings (-20, false))); + + for (const auto& [name, golden] : gldzm_3d_mirp_negdepth_ref_vals) + { + SCOPED_TRACE ("MIRP_ORACLE__" + name); + const double actual = fvals[(int)Nyxus::UserFacing_3D_featureNames.at(name)][0]; + const double frac = name == "3GLDZM_ZDE" ? 1e6 : 1e9; + ASSERT_TRUE (agrees_gt (actual, golden, frac)) << name << " actual=" << std::setprecision(17) << actual; + } +} \ No newline at end of file diff --git a/tests/test_3d_glrlm_invariant.h b/tests/test_3d_glrlm_invariant.h new file mode 100644 index 000000000..27d3bcb0f --- /dev/null +++ b/tests/test_3d_glrlm_invariant.h @@ -0,0 +1,48 @@ +#pragma once + +// Invariants of the 3D GLRLM family: bounds its features hold by construction, whatever the +// configuration. Claims no oracle (SPEC 2). + +#include "test_3d_glrlm_regression.h" // gtest, the environment, run_3d_glrlm_pipeline() on the ut_ phantom + +// Run Percentage is runs over the ROI's voxels, short-run emphasis averages 1/j^2, and the two +// normalised non-uniformities divide a sum of squares by the square of its sum, so all four lie in +// [0, 1]; long-run emphasis averages j^2 and is at least 1. Each holds per direction, so every one of +// the 13 directions is checked rather than their mean, which can stay in range while single +// directions leave it. +// +// The sweep crosses all three binning schemes: PyRadiomics bin counts, no binning, and MATLAB levels. +// The ut_ ROI leaves background inside its bounding box, and MATLAB binning sends intensity 0 to +// level 1, the level the ROI's darkest voxels carry, so the MATLAB depths are where a run counted +// outside the ROI would push RP past 1. +void test_3d_glrlm_bounded_features_invariant() +{ + using F = Nyxus::Feature3D; + + for (int depth : { -100, -20, 0, 32, 64, 128, 256 }) + { + SCOPED_TRACE ("GLRLM_GREYDEPTH=" + std::to_string (depth)); + Environment e; + int label = -1; + run_3d_glrlm_pipeline (e, depth, depth, label); + if (::testing::Test::HasFatalFailure()) + return; + const auto& fv = e.roiData[label].fvals; + + for (F fc : { F::GLRLM_RP, F::GLRLM_SRE, F::GLRLM_RLNN, F::GLRLM_GLNN }) + { + const std::vector& v = fv[(int) fc]; + ASSERT_EQ (v.size(), 13u) << "feature " << (int) fc; + for (size_t a = 0; a < v.size(); a++) + { + EXPECT_GE (v[a], 0.0) << "feature " << (int) fc << ", direction " << a; + EXPECT_LE (v[a], 1.0) << "feature " << (int) fc << ", direction " << a; + } + } + + const std::vector& lre = fv[(int) F::GLRLM_LRE]; + ASSERT_EQ (lre.size(), 13u); + for (size_t a = 0; a < lre.size(); a++) + EXPECT_GE (lre[a], 1.0) << "LRE, direction " << a; + } +} diff --git a/tests/test_3d_glrlm_pyradiomics.h b/tests/test_3d_glrlm_pyradiomics.h index 57e13c70a..37e502525 100644 --- a/tests/test_3d_glrlm_pyradiomics.h +++ b/tests/test_3d_glrlm_pyradiomics.h @@ -550,9 +550,8 @@ void test_3d_glrlm_ave_pyradiomics() {F::GLRLM_RLN_AVE, "3GLRLM_RLN"}, {F::GLRLM_RLNN_AVE, "3GLRLM_RLNN"}, {F::GLRLM_RV_AVE, "3GLRLM_RV"}, {F::GLRLM_SRE_AVE, "3GLRLM_SRE"}, {F::GLRLM_SRHGLE_AVE, "3GLRLM_SRHGLE"}, {F::GLRLM_SRLGLE_AVE, "3GLRLM_SRLGLE"}, - // RP is only in its mathematical bound [0,1] at this recipe's binCount binning; it exceeds 1 - // at positive GLRLM_GREYDEPTH values (see the audit report), so this row vets it here and - // says nothing about other configs. + // vetted at this recipe's binCount binning; its [0,1] bound at every binning is + // test_3d_glrlm_bounded_features_invariant's {F::GLRLM_RP_AVE, "3GLRLM_RP"}, {F::GLRLM_RE_AVE, "3GLRLM_RE"}, }; diff --git a/tests/test_3d_glrlm_regression.h b/tests/test_3d_glrlm_regression.h index 0d5dd6fd1..95214c7c3 100644 --- a/tests/test_3d_glrlm_regression.h +++ b/tests/test_3d_glrlm_regression.h @@ -48,7 +48,7 @@ static const ref_vals_map glrlm_3d_regression_ref_vals{ // Every slot of every feature in the family, not just the direction-averaged one: a base feature // holds one value per 3D angle and its *_AVE twin holds their mean, so two per-angle errors of // opposite sign leave the mean where it was. The 16 mean pins each equal the arithmetic mean of -// their own 13 per-angle pins to rel<=2.9e-16, which is checkable without running anything. +// their own 13 per-angle pins to rel<=1.5e-16, which is checkable without running anything. // // The whole table is Nyxus' own output, so it claims no vetting (SPEC 1): it is a drift guard on // the grey64 configuration, which nothing else in the tree exercises. The family is vetted against @@ -58,42 +58,38 @@ static const ref_vals_map glrlm_3d_regression_ref_vals{ // Where these goldens came from: tests/vetting/audit/glrlm_3d_golden_regen.md, "grey64 table and // the retired sweep". static const ref_vals_map> glrlm_3d_regression_grey64_ref_vals{ - {"3GLRLM_GLN", { 9658.5508820166888, 7864.294342649604, 9658.5508820166888, 7275.7038435192935, 5294.9954101273315, 7275.7038435192935, 9658.5508820166888, 7864.294342649604, 9658.5508820166888, 7924.8644339692491, 6390.2164957135401, 7924.8644339692491, 5811.0057485452298 }}, - {"3GLRLM_GLNN", { 0.034399366337045732, 0.029205112718638744, 0.034399366337045732, 0.027687433760253038, 0.024499349506437538, 0.027687433760253038, 0.034399366337045732, 0.029205112718638744, 0.034399366337045732, 0.032597318270314542, 0.026907081062577012, 0.032597318270314542, 0.025617200443242946 }}, - {"3GLRLM_GLV", { 327.7802163448697, 292.56886329307753, 327.7802163448697, 278.31013715040581, 216.56464294608497, 278.31013715040581, 327.7802163448697, 292.56886329307753, 327.7802163448697, 320.19290160789063, 272.27397969014555, 320.19290160789063, 254.88131322305716 }}, - {"3GLRLM_HGLRE", { 1775.7218005748334, 1831.3071324059151, 1775.7218005748334, 1859.6880280082198, 2035.5211541308854, 1859.6880280082198, 1775.7218005748334, 1831.3071324059151, 1775.7218005748334, 1821.6395271354179, 1885.0107287824433, 1821.6395271354179, 1922.2664256744843 }}, - {"3GLRLM_LGLRE", { 0.12853636684847319, 0.10051498661830537, 0.12853636684847319, 0.089851644520867982, 0.049513382538602824, 0.089851644520867982, 0.12853636684847319, 0.10051498661830537, 0.12853636684847319, 0.11989559650661127, 0.084295059820187923, 0.11989559650661127, 0.072161258942153098 }}, - {"3GLRLM_LRE", { 14.308515298617765, 22.86616804937648, 14.308515298617765, 25.293035999695562, 76.245336097127634, 25.293035999695562, 14.308515298617765, 22.86616804937648, 14.308515298617765, 21.584738024136826, 36.843514728917185, 21.584738024136826, 40.795238934932108 }}, - {"3GLRLM_LRHGLE", { 2406.8495353964177, 2556.7349727790611, 2406.8495353964177, 2753.8799908668848, 4756.7726532425231, 2753.8799908668848, 2406.8495353964177, 2556.7349727790611, 2406.8495353964177, 5925.944733746308, 4461.5637410944373, 5925.944733746308, 5678.3747839887146 }}, - {"3GLRLM_LRLGLE", { 12.943326782170793, 21.435979552767879, 12.943326782170793, 23.741684325170944, 73.40752988640304, 23.741684325170944, 12.943326782170793, 21.435979552767879, 12.943326782170793, 17.946921938258999, 34.234109125406505, 17.946921938258999, 37.410444484700058 }}, - {"3GLRLM_RE", { 6.1895191308639665, 6.2191739841548701, 6.1895191308639665, 6.2427463984415068, 6.3170415653715084, 6.2427463984415068, 6.1895191308639665, 6.2191739841548701, 6.1895191308639665, 6.4130842950857003, 6.4123119828378545, 6.4130842950857003, 6.442818000694567 }}, - {"3GLRLM_RLN", { 192919.13010324919, 193629.31793908155, 192919.13010324919, 188199.01541974276, 139897.28560852827, 188199.01541974276, 192919.13010324919, 193629.31793908155, 192919.13010324919, 158721.69890668575, 162887.15052296498, 158721.69890668575, 154513.36159407513 }}, - {"3GLRLM_RLNN", { 0.68709021787129709, 0.71906846433455962, 0.68709021787129709, 0.71618469982396971, 0.64728903986770936, 0.71618469982396971, 0.68709021787129709, 0.71906846433455962, 0.68709021787129709, 0.65286943124084074, 0.68586373655939981, 0.65286943124084074, 0.68115571148860488 }}, - // 3GLRLM_RP is runs/voxels and cannot exceed 1. Four of these thirteen angles do, at - // 1.0231; the mean below stays at 0.9401 and hides it. The pins record what Nyxus - // computes today so the eventual fix shows up as a diff -- the defect itself is filed, - // see tests/vetting/audit/glrlm_3d_pyradiomics_vetting_report.md. - {"3GLRLM_RP", { 1.0231204815764925, 0.98121939132462688, 1.0231204815764925, 0.95754139458955223, 0.78754664179104472, 0.95754139458955223, 1.0231204815764925, 0.98121939132462688, 1.0231204815764925, 0.8858806553171642, 0.86539470615671643, 0.8858806553171642, 0.82657999067164178 }}, - {"3GLRLM_RV", { 10.456897437611142, 18.678574666900062, 10.456897437611142, 20.895781173091144, 69.744874729144186, 20.895781173091144, 10.456897437611142, 18.678574666900062, 10.456897437611142, 16.447303344414838, 31.459970552104785, 16.447303344414838, 34.894220469305615 }}, - {"3GLRLM_SRE", { 0.84579294864193277, 0.86319730506307568, 0.84579294864193277, 0.86144018935068922, 0.82810378265611795, 0.86144018935068922, 0.84579294864193277, 0.86319730506307568, 0.84579294864193277, 0.82602159233427142, 0.84585814804218318, 0.82602159233427142, 0.84275775431181899 }}, - {"3GLRLM_SRHGLE", { 1704.2599012769638, 1751.4379431521975, 1704.2599012769638, 1773.2955735300955, 1848.1386035867843, 1773.2955735300955, 1704.2599012769638, 1751.4379431521975, 1704.2599012769638, 1698.037480359684, 1744.4559054513027, 1698.037480359684, 1771.7804216516631 }}, - {"3GLRLM_SRLGLE", { 0.02688849995052962, 0.020762832669439898, 0.02688849995052962, 0.013282277299082696, 0.0080087704834321174, 0.013282277299082696, 0.02688849995052962, 0.020762832669439898, 0.02688849995052962, 0.021347857736332493, 0.015116231043675595, 0.021347857736332493, 0.0067679262956016001 }}, - {"3GLRLM_GLNN_AVE", { 0.03027698660452716 }}, - {"3GLRLM_GLN_AVE", { 7866.1651094407034 }}, - {"3GLRLM_GLV_AVE", { 295.15266194934725 }}, - {"3GLRLM_HGLRE_AVE", { 1843.919606614327 }}, - {"3GLRLM_LGLRE_AVE", { 0.10312612492203121 }}, - {"3GLRLM_LRE_AVE", { 26.969695007835828 }}, - {"3GLRLM_LRHGLE_AVE", { 3615.1714395919889 }}, - {"3GLRLM_LRLGLE_AVE", { 24.851889404429883 }}, - {"3GLRLM_RE_AVE", { 6.2830967252095355 }}, - {"3GLRLM_RLNN_AVE", { 0.6876088115538187 }}, - {"3GLRLM_RLN_AVE", { 177698.02943612199 }}, - {"3GLRLM_RP_AVE", { 0.94009893441446601 }}, - {"3GLRLM_RV_AVE", { 22.305382605370099 }}, - {"3GLRLM_SRE_AVE", { 0.84624689639030193 }}, - {"3GLRLM_SRHGLE_AVE", { 1740.5351176831971 }}, - {"3GLRLM_SRLGLE_AVE", { 0.019094835618041383 }}, + {"3GLRLM_GLN", { 5805.5128831349166, 5751.6418651857839, 5805.5128831349166, 5691.2604749887187, 5023.5925197999568, 5691.2604749887187, 5805.5128831349166, 5751.6418651857839, 5805.5128831349166, 5069.4198122460421, 5159.1255950739824, 5069.4198122460421, 5008.3592577820828 }}, + {"3GLRLM_GLNN", { 0.023710003402564444, 0.023730049200776409, 0.023710003402564444, 0.023779772345481249, 0.024439045903792433, 0.023779772345481249, 0.023710003402564444, 0.023730049200776409, 0.023710003402564444, 0.023676707357181085, 0.023707037933434344, 0.023676707357181085, 0.023780028003067645 }}, + {"3GLRLM_GLV", { 144.91508073637226, 144.86129129475947, 144.91508073637226, 143.91390236292509, 133.89874619769103, 143.91390236292509, 144.91508073637226, 144.86129129475947, 144.91508073637226, 144.39097879874467, 144.32600985229575, 144.39097879874467, 142.84085038335559 }}, + {"3GLRLM_HGLRE", { 2036.0863286434828, 2034.4413354347341, 2036.0863286434828, 2041.7886952016445, 2140.1591001965403, 2041.7886952016445, 2036.0863286434828, 2034.4413354347341, 2036.0863286434828, 2068.2689645509317, 2057.0494256042643, 2068.2689645509317, 2070.3031546160714 }}, + {"3GLRLM_LGLRE", { 0.00068634691802812141, 0.00068683860170490427, 0.00068634691802812141, 0.00068196123875489511, 0.00062867705784865329, 0.00068196123875489511, 0.00068634691802812141, 0.00068683860170490427, 0.00068634691802812141, 0.00067394352953326791, 0.00067733823553023386, 0.00067394352953326791, 0.00066976230432264213 }}, + {"3GLRLM_LRE", { 1.5668293479814583, 1.5902763452128494, 1.5668293479814583, 1.7048117259706181, 2.9865146237521647, 1.7048117259706181, 1.5668293479814583, 1.5902763452128494, 1.5668293479814583, 4.134435570501144, 2.8502159727966179, 4.134435570501144, 3.6489088940801095 }}, + {"3GLRLM_LRHGLE", { 2745.1109268750893, 2816.6771406645817, 2745.1109268750893, 2997.6187722494274, 4924.2391562396624, 2997.6187722494274, 2745.1109268750893, 2816.6771406645817, 2745.1109268750893, 6708.3172201204989, 4831.6143736788899, 6708.3172201204989, 6075.6132034262055 }}, + {"3GLRLM_LRLGLE", { 0.0013577991773710892, 0.001360280265647809, 0.0013577991773710892, 0.0014699537396934757, 0.0027565203084798182, 0.0014699537396934757, 0.0013577991773710892, 0.001360280265647809, 0.0013577991773710892, 0.0038297141558305487, 0.0025321404790105465, 0.0038297141558305487, 0.0033104804539068507 }}, + {"3GLRLM_RE", { 5.8527823565279871, 5.8758725757888692, 5.8527823565279871, 5.8989806972895886, 6.1402291690487383, 5.8989806972895886, 5.8527823565279871, 5.8758725757888692, 5.8527823565279871, 6.0819282846556231, 6.1049751995701191, 6.0819282846556231, 6.1396531960727465 }}, + {"3GLRLM_RLN", { 210053.24439770475, 206825.59587091237, 210053.24439770475, 201786.65793124196, 144672.07106579229, 201786.65793124196, 210053.24439770475, 206825.59587091237, 210053.24439770475, 172773.36070244267, 172629.57323775388, 172773.36070244267, 164500.6917744478 }}, + {"3GLRLM_RLNN", { 0.8578678989512355, 0.85331835344343288, 0.8578678989512355, 0.84312443773186185, 0.70380855370698148, 0.84312443773186185, 0.8578678989512355, 0.85331835344343288, 0.8578678989512355, 0.80693737192304271, 0.79326152576855935, 0.80693737192304271, 0.78106039434812735 }}, + {"3GLRLM_RP", { 0.89222466767723885, 0.88319875233208955, 0.89222466767723885, 0.87209946361940294, 0.7490234375, 0.87209946361940294, 0.89222466767723885, 0.88319875233208955, 0.89222466767723885, 0.78019327192164178, 0.79298332555970152, 0.78019327192164178, 0.76744694496268662 }}, + {"3GLRLM_RV", { 0.31065029367668973, 0.30829086537405376, 0.31065029367668973, 0.38998670143266545, 1.2040981583754526, 0.38998670143266545, 0.31065029367668973, 0.30829086537405376, 0.31065029367668973, 2.4915943228009287, 1.2599422259983606, 2.4915943228009287, 1.9510434211208152 }}, + {"3GLRLM_SRE", { 0.93966351987082797, 0.93654898758192096, 0.93966351987082797, 0.93186200804813868, 0.86276257105390042, 0.93186200804813868, 0.93966351987082797, 0.93654898758192096, 0.93966351987082797, 0.91427342440869985, 0.9071933958275944, 0.91427342440869985, 0.90098267001742083 }}, + {"3GLRLM_SRHGLE", { 1954.2569455606754, 1945.7965049746131, 1954.2569455606754, 1947.0161364021153, 1943.1827323197676, 1947.0161364021153, 1954.2569455606754, 1945.7965049746131, 1954.2569455606754, 1928.0352233415795, 1903.7352301302546, 1928.0352233415795, 1908.292297877485 }}, + {"3GLRLM_SRLGLE", { 0.00061986386941450156, 0.00061804559373080856, 0.00061986386941450156, 0.00060778325195095389, 0.00048905536543503039, 0.00060778325195095389, 0.00061986386941450156, 0.00061804559373080856, 0.00061986386941450156, 0.00059610754800567688, 0.00059216730167935977, 0.00059610754800567688, 0.00057845474384322329 }}, + {"3GLRLM_GLNN_AVE", { 0.02377993717364844 }}, + {"3GLRLM_GLN_AVE", { 5495.2133238489823 }}, + {"3GLRLM_GLV_AVE", { 143.61986725320691 }}, + {"3GLRLM_HGLRE_AVE", { 2053.9119219511867 }}, + {"3GLRLM_LGLRE_AVE", { 0.00067743476998462693 }}, + {"3GLRLM_LRE_AVE", { 2.3547695512249192 }}, + {"3GLRLM_LRHGLE_AVE", { 3989.0105159164718 }}, + {"3GLRLM_LRLGLE_AVE", { 0.00210386417486348 }}, + {"3GLRLM_RE_AVE", { 5.9622730850978245 }}, + {"3GLRLM_RLNN_AVE", { 0.82433556890963733 }}, + {"3GLRLM_RLN_AVE", { 191137.42635984672 }}, + {"3GLRLM_RP_AVE", { 0.84225656572904717 }}, + {"3GLRLM_RV_AVE", { 0.92595605841666806 }}, + {"3GLRLM_SRE_AVE", { 0.92268935049690348 }}, + {"3GLRLM_SRHGLE_AVE", { 1939.533367077448 }}, + {"3GLRLM_SRLGLE_AVE", { 0.00059869274430696139 }}, }; // Defined once, in test_3d_glcm_pyradiomics.h. Every 3D header that needs the segmented phantom diff --git a/tests/test_3d_glszm_common.h b/tests/test_3d_glszm_common.h index ff4aa9de0..f366d9db1 100644 --- a/tests/test_3d_glszm_common.h +++ b/tests/test_3d_glszm_common.h @@ -231,6 +231,12 @@ static void run_3d_glszm_on_volume ( r.aux_max = v; } + // the cube is the ROI's bounding box, its corner at the origin: calculate() places the voxel + // cloud in the cube through it + r.aabb.init_x (0); r.aabb.update_x (w - 1); + r.aabb.init_y (0); r.aabb.update_y (h - 1); + r.aabb.init_z (0); r.aabb.update_z (d - 1); + ASSERT_NO_THROW(r.initialize_fvals()); ASSERT_NO_THROW(f.calculate(r, s)); f.save_value(r.fvals); diff --git a/tests/test_3d_glszm_mechanics.h b/tests/test_3d_glszm_mechanics.h index a83a335f7..643b8e6a2 100644 --- a/tests/test_3d_glszm_mechanics.h +++ b/tests/test_3d_glszm_mechanics.h @@ -7,17 +7,17 @@ // mock workflow and the Environment graph all arrive with the common header. #include "test_3d_glszm_common.h" // gtest, , , the phantoms, extract_3d_glszm -// compile_feature_settings() zero-fills every family's settings vector and writes back only the -// entries someone remembered, so a family's zero is either its documented default or a degenerate -// value nothing runs at. For GLSZM_GREYDEPTH zero is the documented default -- it selects no binning -// at all, which is the IBSI reading of the raw levels, and --3glszm/greydepth is what overrides it. -// This asserts that a run which passes no such flag still reaches the feature with settings that -// produce numbers, which is the check that would have caught NGTDM_RADIUS coming through at 0. +// compile_feature_settings() starts GLSZM_GREYDEPTH at the coarse grey depth, 64 unless +// --coarseGrayDepth says otherwise -- MATLAB binning into 64 levels -- and 3glszm/greydepth is what +// overrides it for this family alone. This asserts that a run which passes neither reaches the +// feature at that depth and with settings that produce numbers, which is the check that would have +// caught NGTDM_RADIUS coming through at 0. void test_3d_glszm_default_greydepth_mechanics() { Environment e; e.compile_feature_settings(); - ASSERT_EQ (STNGS_GLSZM_GREYDEPTH (e.fsett_D3_GLSZM), 0); + ASSERT_EQ (e.get_coarse_gray_depth(), 64); + ASSERT_EQ (STNGS_GLSZM_GREYDEPTH (e.fsett_D3_GLSZM), 64); auto [ipath, mpath, label] = get_3d_compat_phantom(); std::vector> fvals; diff --git a/tests/test_3d_glszm_regression.h b/tests/test_3d_glszm_regression.h index 73e50b1bb..88057b0a1 100644 --- a/tests/test_3d_glszm_regression.h +++ b/tests/test_3d_glszm_regression.h @@ -4,16 +4,17 @@ // values below are Nyxus' own output, so movement is the only thing they can catch. // // Recipe glszm3d.regression_ut_phantom: bench_ut57_3d (label 57) with GREYDEPTH=64, IBSI=false and -// GLSZM_GREYDEPTH=64, whose positive sign selects MATLAB-style binning into that many levels, so bin 1 -// is the background level and a voxel binned there starts no zone of its own. +// GLSZM_GREYDEPTH=64, whose positive sign selects MATLAB-style binning into that many levels. The +// background is level 0 and starts no zone; every ROI voxel, level 1 included, starts zones of its own +// level. // -// Recipe glszm3d.regression_ut_phantom_nobinning: the same phantom at GLSZM_GREYDEPTH=0, which is the -// value a run that passes no --3glszm/greydepth reaches the feature with. It is a third binning -// scheme rather than a coarser version of the second -- the background is intensity 0 there and bin 1 -// under MATLAB binning -- so it gets its own table. Nothing vets it: PyRadiomics has no counterpart -// for reading raw levels off an unbinned volume, so these are Nyxus' own numbers and catch movement -// only. What the family's default DOES have an oracle for is the same setting on a fixture small -// enough for one: test_3d_glszm_ibsi_gapped_pyradiomics. +// Recipe glszm3d.regression_ut_phantom_nobinning: the same phantom at GLSZM_GREYDEPTH=0, no binning, +// which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects. A run that names neither bins at the coarse +// grey depth, 64, which is the recipe above. It is a third binning scheme rather than a coarser version +// of the second -- its levels are the raw intensities, not 64 levels over [0, max] -- so it gets its +// own table. Nothing vets it here: PyRadiomics has no counterpart for reading raw levels off an +// unbinned volume, so these are Nyxus' own numbers and catch movement only. The same setting does +// have an oracle on a fixture small enough for one: test_3d_glszm_ibsi_gapped_pyradiomics. // // Pins are the program's own %.17g output -- a value truncated to five digits eats a third of a // rel=1e-3 band before the test starts. Regenerate them with @@ -217,11 +218,11 @@ void test_3d_glszm_ze_regression() { assert_3d_glszm_feature_regression (Nyxus::Feature3D::GLSZM_ZE, "3GLSZM_ZE"); } -// The family at the settings a run with no --3glszm/greydepth flag reaches it with, pinned rather -// than merely asserted finite (test_3d_glszm_mechanics.h does the finiteness). One case for the +// The family with no binning, pinned rather than merely asserted finite (test_3d_glszm_mechanics.h +// does the finiteness, at the default depth). One case for the // sixteen because one phantom read answers all of them, and at this setting the matrix is Ng = the // phantom's largest raw level wide, which is not a read to repeat sixteen times. -void test_3d_glszm_default_greydepth_regression() +void test_3d_glszm_no_binning_regression() { auto [ipath, mpath, label] = get_3d_segmented_phantom(); Fsettings s = make_glszm3d_settings (64/*greydepth, inert for this family*/, 0/*no binning*/); diff --git a/tests/test_3d_ngldm_common.h b/tests/test_3d_ngldm_common.h index 7fed706a6..2db41a91e 100644 --- a/tests/test_3d_ngldm_common.h +++ b/tests/test_3d_ngldm_common.h @@ -17,13 +17,13 @@ // get_3d_segmented_phantom is bench_ut57_3d (phantoms/ut_inten.nii + ut_mask57.nii, label 57). static std::tuple get_3d_segmented_phantom(); -// Fixture (SPEC 6.3.1): loads the segmented phantom, runs D3_NGLDM_feature at GREYDEPTH=64 / -// IBSI=false and hands one feature's value back. Both judging files in this family -- the MIRP -// oracle and the regression drift guards -- read the SAME Nyxus run through this helper, which is -// what makes the two comparisons in +// Fixture (SPEC 6.3.1): loads the segmented phantom, runs D3_NGLDM_feature at the caller's GREYDEPTH +// and IBSI (64 / false unless stated) and hands one feature's value back. Both judging files in this +// family -- the MIRP oracle and the regression drift guards -- read the SAME Nyxus run through this +// helper, which is what makes the two comparisons in // tests/vetting/audit/ngldm_3d_mirp_vetting_report.md comparisons of one number rather than of two // runs that could drift apart. Goldens stay in their respective oracle/regression files. -void calculate_3d_ngldm_feature_value (const std::string& fname, const Nyxus::Feature3D& expecting_fcode, double& out, bool ibsi = false) +void calculate_3d_ngldm_feature_value (const std::string& fname, const Nyxus::Feature3D& expecting_fcode, double& out, bool ibsi = false, int greydepth = 64) { // get segment info auto [ipath, mpath, label] = get_3d_segmented_phantom(); @@ -46,16 +46,16 @@ void calculate_3d_ngldm_feature_value (const std::string& fname, const Nyxus::Fe // (4) buffers ASSERT_NO_THROW(allocateTrivialRoisBuffers_3D(batch, e.roiData, e.hostCache)); - // (5) feature settings. IBSI is the family's second axis and reaches to_grayscale as - // disable_binning, so ibsi=false is the GREYDEPTH=64 ladder both mirp_samelevels and the - // regression pins use, and ibsi=true turns binning off and makes the raw intensity the grey - // level -- the Nyxus half of ngldm3d.mirp_ibsi_rawlevels. + // (5) feature settings. IBSI is the family's second axis and keeps the raw intensity as the grey + // level, so ibsi=false at the default GREYDEPTH=64 is the ladder both mirp_samelevels and the + // regression pins use, ibsi=true is the Nyxus half of ngldm3d.mirp_ibsi_rawlevels, and a negative + // 'greydepth' is the PyRadiomics-style binning of ngldm3d.mirp_fbn20_negdepth. Fsettings s; s.resize((int)NyxSetting::__COUNT__); s[(int)NyxSetting::SOFTNAN].rval = 0.0; s[(int)NyxSetting::TINY].rval = 0.0; s[(int)NyxSetting::SINGLEROI].bval = false; - s[(int)NyxSetting::GREYDEPTH].ival = 64; + s[(int)NyxSetting::GREYDEPTH].ival = greydepth; s[(int)NyxSetting::PIXELSIZEUM].rval = 100; s[(int)NyxSetting::PIXELDISTANCE].ival = 5; s[(int)NyxSetting::USEGPU].bval = false; diff --git a/tests/test_3d_ngldm_mechanics.h b/tests/test_3d_ngldm_mechanics.h new file mode 100644 index 000000000..b2478b35b --- /dev/null +++ b/tests/test_3d_ngldm_mechanics.h @@ -0,0 +1,24 @@ +#pragma once + +// Mechanics of the 3D NGLDM family: what a setting does to the grey levels the matrix is built on, +// rather than the values against a reference. Claims no oracle (SPEC 2). + +// Nothing of its own: gtest, and the phantom run arrive with the common header. +#include "test_3d_ngldm_common.h" + +// A coarse grey depth of 0 bins nothing, so NGLDM reads the raw levels -- the same grey levels IBSI +// mode reads -- and every feature equals the IBSI run bit for bit, on the segmented phantom's raw +// levels. A 0 that collapsed them to one level would move every grey-level feature. +void test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics() +{ + for (const auto& [name, fc] : Nyxus::UserFacing_3D_featureNames) + { + if (name.rfind ("3NGLDM_", 0) != 0) + continue; + SCOPED_TRACE (name); + double none = 0.0, ibsi = 0.0; + ASSERT_NO_FATAL_FAILURE (calculate_3d_ngldm_feature_value (name, fc, none, false, 0)); + ASSERT_NO_FATAL_FAILURE (calculate_3d_ngldm_feature_value (name, fc, ibsi, true, 64)); + ASSERT_EQ (none, ibsi); + } +} diff --git a/tests/test_3d_ngldm_mirp.h b/tests/test_3d_ngldm_mirp.h index e5dae77ff..7cdc7408c 100644 --- a/tests/test_3d_ngldm_mirp.h +++ b/tests/test_3d_ngldm_mirp.h @@ -325,3 +325,45 @@ void test_3d_ngldm_dump_ibsi_mirp() { double v = 0.0; calculate_3d_ngldm_feature_value ("3NGLDM_DCENE", Feature3D::NGLDM_DCENE, v, true); std::cout << "[3DNGLDM-IBSI-REGEN]\t\t{ \"3NGLDM_DCENE\",\t" << std::setprecision(17) << v << " },\n"; } } + +// --------------------------------------------------------------------------------------------------- +// The negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH = -20 bins the ROI +// into 20 PyRadiomics-style bins over its own [min, max], which is IBSI's fixed bin number, and MIRP +// runs base_discretisation_method="fixed_bin_number", n_bins=20 -- each tool discretising for itself, +// so unlike mirp_samelevels this recipe covers the binning as well as the matrix. MIRP is handed the +// integer levels Nyxus loads the float phantom as (the loader's shift, not a binning step). +// +// Provenance (SPEC 6.4): tool=mirp 2.6.0, by_slice=False, distance 1, difference level 0, the same +// segmented phantom and label 57; generator=tests/vetting/oracles/gen_ngldm3d_mirp.py +// (re-verifies every pin with --check). Measured residual 5.1e-16 worst case; asserted at rel=1e-9, +// and at rel=1e-6 for 3NGLDM_DCENT, the family's one logarithm. +static const ref_vals_map ngldm_3d_mirp_negdepth_ref_vals{ + { "3NGLDM_LDE", 0.043474348242984726 }, // ngl_lde_d1_a0.0_3d_fbn_n20 + { "3NGLDM_HDE", 107.1934468283582 }, // ngl_hde_d1_a0.0_3d_fbn_n20 + { "3NGLDM_LGLCE", 0.09507277967840505 }, // ngl_lgce_d1_a0.0_3d_fbn_n20 + { "3NGLDM_HGLCE", 136.15380130597015 }, // ngl_hgce_d1_a0.0_3d_fbn_n20 + { "3NGLDM_LDLGLE", 0.0007735897913493037 }, // ngl_ldlge_d1_a0.0_3d_fbn_n20 + { "3NGLDM_LDHGLE", 8.941485494088381 }, // ngl_ldhge_d1_a0.0_3d_fbn_n20 + { "3NGLDM_HDLGLE", 36.22286208307041 }, // ngl_hdlge_d1_a0.0_3d_fbn_n20 + { "3NGLDM_HDHGLE", 6211.256996268657 }, // ngl_hdhge_d1_a0.0_3d_fbn_n20 + { "3NGLDM_GLNU", 13820.251399253732 }, // ngl_glnu_d1_a0.0_3d_fbn_n20 + { "3NGLDM_GLNUN", 0.05035947483986464 }, // ngl_glnu_norm_d1_a0.0_3d_fbn_n20 + { "3NGLDM_DCNU", 20026.524253731342 }, // ngl_dcnu_d1_a0.0_3d_fbn_n20 + { "3NGLDM_DCNUN", 0.07297444996841237 }, // ngl_dcnu_norm_d1_a0.0_3d_fbn_n20 + { "3NGLDM_GLV", 34.10752476050396 }, // ngl_gl_var_d1_a0.0_3d_fbn_n20 + { "3NGLDM_DCV", 31.151427009159327 }, // ngl_dc_var_d1_a0.0_3d_fbn_n20 + { "3NGLDM_DCENT", 7.863915779016927 }, // ngl_dc_entr_d1_a0.0_3d_fbn_n20 + { "3NGLDM_DCENE", 0.00509771362766972 } // ngl_dc_energy_d1_a0.0_3d_fbn_n20 +}; + +void test_3d_ngldm_negative_greydepth_mirp() +{ + for (const auto& [name, golden] : ngldm_3d_mirp_negdepth_ref_vals) + { + SCOPED_TRACE ("MIRP_ORACLE__" + name); + double actual = 0.0; + ASSERT_NO_FATAL_FAILURE (calculate_3d_ngldm_feature_value (name, Nyxus::UserFacing_3D_featureNames.at(name), actual, false, -20)); + const double frac = name == "3NGLDM_DCENT" ? 1e6 : 1e9; + ASSERT_TRUE (agrees_gt (actual, golden, frac)) << name << " actual=" << std::setprecision(17) << actual; + } +} \ No newline at end of file diff --git a/tests/test_all.cc b/tests/test_all.cc index 693b03614..c05efd046 100644 --- a/tests/test_all.cc +++ b/tests/test_all.cc @@ -75,6 +75,7 @@ #include "test_2d_ngldm_ibsi.h" #include "test_2d_ngldm_mirp.h" #include "test_2d_ngldm_regression.h" +#include "test_2d_ngldm_mechanics.h" #include "test_2d_ngtdm_ibsi.h" #include "test_2d_ngtdm_mirp.h" #include "test_2d_ngtdm_mechanics.h" @@ -119,6 +120,7 @@ #include "test_3d_morphology_pyradiomics.h" #include "test_3d_ngldm_mirp.h" #include "test_3d_ngldm_regression.h" +#include "test_3d_ngldm_mechanics.h" #include "test_3d_firstorder_pyradiomics.h" #include "test_3d_firstorder_regression.h" #include "test_3d_firstorder_matlab.h" @@ -131,6 +133,8 @@ #include "test_3d_ngtdm_mechanics.h" #include "test_3d_glrlm_pyradiomics.h" #include "test_3d_glrlm_regression.h" +#include "test_3d_glrlm_invariant.h" +#include "test_texture_binning_mechanics.h" #include "test_3d_glszm_pyradiomics.h" #include "test_3d_glszm_regression.h" #include "test_3d_glszm_mechanics.h" @@ -559,8 +563,8 @@ TEST(TEST_NYXUS, TEST_3D_GLSZM_DUMP_REGRESSION) { ASSERT_NO_THROW(test_3d_glszm_dump_regression()); } -TEST(TEST_NYXUS, TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION) { - ASSERT_NO_THROW(test_3d_glszm_default_greydepth_regression()); +TEST(TEST_NYXUS, TEST_3D_GLSZM_NO_BINNING_REGRESSION) { + ASSERT_NO_THROW(test_3d_glszm_no_binning_regression()); } TEST(TEST_NYXUS, TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION) { @@ -1255,6 +1259,10 @@ TEST(TEST_NYXUS, TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP) { ASSERT_NO_THROW(test_3d_gldzm_zde_radiomics_mirp()); } +TEST(TEST_NYXUS, TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP) { + ASSERT_NO_THROW(test_3d_gldzm_negative_greydepth_mirp()); +} + //***** 3D GLDZM regression ***** TEST(TEST_NYXUS, TEST_3D_GLDZM_GLM_REGRESSION) { @@ -1415,6 +1423,14 @@ TEST(TEST_NYXUS, TEST_3D_NGLDM_DCENE_MIRP) { ASSERT_NO_THROW(test_3d_ngldm_dcene_mirp()); } +TEST(TEST_NYXUS, TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP) { + ASSERT_NO_THROW(test_3d_ngldm_negative_greydepth_mirp()); +} + +TEST(TEST_NYXUS, TEST_3D_NGLDM_ZERO_GREYDEPTH_EQUALS_IBSI_MECHANICS) { + ASSERT_NO_THROW(test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics()); +} + //***** 3D NGLDM vetted vs MIRP at IBSI=true, where the raw intensity is the grey level ***** TEST(TEST_NYXUS, TEST_3D_NGLDM_LDE_IBSI_MIRP) { @@ -1658,6 +1674,30 @@ TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_UNREGISTERED_TYPE_REFUSED_MECHANICS) { ASSERT_NO_FATAL_FAILURE(test_feature_settings_unregistered_type_refused_mechanics()); } +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_COARSE_GRAY_DEPTH_REACHES_EVERY_TEXTURE_FAMILY_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_coarse_gray_depth_reaches_every_texture_family_mechanics()); +} + +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_FAMILY_GREYDEPTH_OVERRIDES_COARSE_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_family_greydepth_overrides_coarse_mechanics()); +} + +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_COARSE_GRAY_DEPTH_CLI_ACCEPTED_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_coarse_gray_depth_cli_accepted_mechanics()); +} + +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_COARSE_GRAY_DEPTH_CLI_REFUSED_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_coarse_gray_depth_cli_refused_mechanics()); +} + +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_GREY_DEPTH_PARSE_RANGE_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_grey_depth_parse_range_mechanics()); +} + +TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_GREYDEPTH_METAPARAM_REFUSED_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_feature_settings_greydepth_metaparam_refused_mechanics()); +} + //***** Pixel intensity features ***** TEST(TEST_NYXUS, TEST_2D_FIRSTORDER_PYRADIOMICS) @@ -2979,6 +3019,11 @@ TEST(TEST_NYXUS, TEST_2D_GLCM_BUG_OFFSET_DEFAULT_IS_ONE_MECHANICS) ASSERT_NO_THROW(test_2d_glcm_bug_offset_default_is_one_mechanics()); } +TEST(TEST_NYXUS, TEST_2D_GLCM_OWN_GREYDEPTH_BINS_THE_MATRIX_MECHANICS) +{ + ASSERT_NO_THROW(test_2d_glcm_own_greydepth_bins_the_matrix_mechanics()); +} + //***** PyRadiomics tests of 2D GLDM ***** TEST(TEST_NYXUS, TEST_2D_GLDM_SDE_PYRADIOMICS) @@ -3551,6 +3596,8 @@ TEST(TEST_NYXUS, TEST_2D_NGLDM_DCP_MIRP) { ASSERT_NO_THROW(test_2d_ngldm_dcp_ TEST(TEST_NYXUS, TEST_2D_NGLDM_DCV_MIRP) { ASSERT_NO_THROW(test_2d_ngldm_dcv_mirp()); } TEST(TEST_NYXUS, TEST_2D_NGLDM_DCENT_MIRP) { ASSERT_NO_THROW(test_2d_ngldm_dcent_mirp()); } TEST(TEST_NYXUS, TEST_2D_NGLDM_DCENE_MIRP) { ASSERT_NO_THROW(test_2d_ngldm_dcene_mirp()); } +TEST(TEST_NYXUS, TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP) { ASSERT_NO_THROW(test_2d_ngldm_negative_greydepth_mirp()); } +TEST(TEST_NYXUS, TEST_2D_NGLDM_ZERO_GREYDEPTH_EQUALS_IBSI_MECHANICS) { ASSERT_NO_THROW(test_2d_ngldm_zero_greydepth_equals_ibsi_mechanics()); } //***** 2D intensity ***** @@ -3943,6 +3990,10 @@ TEST(TEST_NYXUS, TEST_2D_GLDZM_ZDE_MIRP) ASSERT_NO_THROW(test_2d_gldzm_zde_mirp()); } +TEST(TEST_NYXUS, TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP) { + ASSERT_NO_THROW(test_2d_gldzm_negative_greydepth_mirp()); +} + //***** 2D GLDZM drift guards ***** TEST(TEST_NYXUS, TEST_2D_GLDZM_GLM_REGRESSION) @@ -6212,5 +6263,12 @@ TEST(TEST_NYXUS, TEST_3D_GLRLM_SRLGLE_AVE_GREY64_REGRESSION) { ASSERT_NO_THROW(t TEST(TEST_NYXUS, TEST_3D_GLRLM_DUMP_REGRESSION) { ASSERT_NO_THROW(test_3d_glrlm_dump_regression()); } +TEST(TEST_NYXUS, TEST_3D_GLRLM_BOUNDED_FEATURES_INVARIANT) { ASSERT_NO_THROW(test_3d_glrlm_bounded_features_invariant()); } + +TEST(TEST_NYXUS, TEST_TEXTURE_BINNING_ZERO_WIDTH_RANGE_MECHANICS) { ASSERT_NO_THROW(test_texture_binning_zero_width_range_mechanics()); } +TEST(TEST_NYXUS, TEST_TEXTURE_BINNING_NONZERO_RANGE_UNCHANGED_MECHANICS) { ASSERT_NO_THROW(test_texture_binning_nonzero_range_unchanged_mechanics()); } +TEST(TEST_NYXUS, TEST_TEXTURE_BINNING_ROI_CUBE_PLACES_VOXELS_MECHANICS) { ASSERT_NO_THROW(test_texture_binning_roi_cube_places_voxels_mechanics()); } +TEST(TEST_NYXUS, TEST_TEXTURE_BINNING_ROI_CUBE_REFUSES_VOXEL_OUTSIDE_BOX_MECHANICS) { ASSERT_NO_THROW(test_texture_binning_roi_cube_refuses_voxel_outside_box_mechanics()); } + TEST(TEST_NYXUS, TEST_3D_NGLDM_DUMP_REGRESSION) { ASSERT_NO_THROW(test_3d_ngldm_dump_regression()); } TEST(TEST_NYXUS, TEST_3D_NGLDM_DUMP_IBSI_MIRP) { ASSERT_NO_THROW(test_3d_ngldm_dump_ibsi_mirp()); } diff --git a/tests/test_feature_settings_mechanics.h b/tests/test_feature_settings_mechanics.h index 7ae633e64..c8632b7b3 100644 --- a/tests/test_feature_settings_mechanics.h +++ b/tests/test_feature_settings_mechanics.h @@ -4,14 +4,17 @@ // is handed, rather than the values any family computes. Claims no oracle (SPEC 2). #include +#include #include #include #include #include #include #include +#include #include "../src/nyx/environment.h" +#include "../src/nyx/helpers/fsystem.h" #include "../src/nyx/feature_method.h" #include "../src/nyx/feature_settings.h" @@ -187,3 +190,182 @@ void test_feature_settings_unregistered_type_refused_mechanics() ASSERT_THROW (e.get_feature_settings (typeid(FeatureMethod*)), std::runtime_error); ASSERT_THROW (e.get_feature_settings (typeid(Environment)), std::runtime_error); } + +// The coarse grey depth is the binning every texture family starts from: the 2D families and 3D +// GLDZM/NGLDM read the common GREYDEPTH, and the other five 3D families read a grey depth of their +// own, which compile_feature_settings() starts at the same value. Asserted at each sign, because the +// sign is the scheme (positive MATLAB levels, 0 none, negative PyRadiomics bins) and a vector left at +// its zero fill would read as a deliberate "no binning". +void test_feature_settings_coarse_gray_depth_reaches_every_texture_family_mechanics() +{ + for (int depth : { -20, 0, 20 }) + { + SCOPED_TRACE ("coarse grey depth " + std::to_string (depth)); + Environment e; + e.set_coarse_gray_depth (depth); + e.compile_feature_settings(); + + // 2D + ASSERT_EQ (STNGS_GLCM_GREYDEPTH (e.fsett_GLCM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_GLRLM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_GLSZM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_GLDM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_GLDZM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_NGLDM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_NGTDM), depth); + + // 3D + ASSERT_EQ (STNGS_GLCM_GREYDEPTH (e.fsett_D3_GLCM), depth); + ASSERT_EQ (STNGS_GLRLM_GREYDEPTH (e.fsett_D3_GLRLM), depth); + ASSERT_EQ (STNGS_GLSZM_GREYDEPTH (e.fsett_D3_GLSZM), depth); + ASSERT_EQ (STNGS_GLDM_GREYDEPTH (e.fsett_D3_GLDM), depth); + ASSERT_EQ (STNGS_NGTDM_GREYDEPTH (e.fsett_D3_NGTDM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_D3_GLDZM), depth); + ASSERT_EQ (STNGS_NGREYS (e.fsett_D3_NGLDM), depth); + } +} + +// The other direction: a family's own grey-depth metaparameter overrides the coarse grey depth for +// that family alone, so starting every family at the common value takes no per-family control away. +void test_feature_settings_family_greydepth_overrides_coarse_mechanics() +{ + Environment e; + e.set_coarse_gray_depth (64); + e.compile_feature_settings(); + + ASSERT_FALSE (e.set_metaparam ("3glszm/greydepth=-20").has_value()); + ASSERT_FALSE (e.set_metaparam ("glcm/greydepth=16").has_value()); + + ASSERT_EQ (STNGS_GLSZM_GREYDEPTH (e.fsett_D3_GLSZM), -20); + ASSERT_EQ (STNGS_GLCM_GREYDEPTH (e.fsett_GLCM), 16); + + ASSERT_EQ (STNGS_GLRLM_GREYDEPTH (e.fsett_D3_GLRLM), 64); + ASSERT_EQ (STNGS_GLDM_GREYDEPTH (e.fsett_D3_GLDM), 64); + ASSERT_EQ (STNGS_NGTDM_GREYDEPTH (e.fsett_D3_NGTDM), 64); + ASSERT_EQ (STNGS_GLCM_GREYDEPTH (e.fsett_D3_GLCM), 64); + ASSERT_EQ (STNGS_NGREYS (e.fsett_GLCM), 64); +} + +// Parses a command line whose only optional argument is --coarseGrayDepth=; the directories are +// the temp directory, which exists, so the depth is the one thing that can refuse the line +static bool parse_coarse_gray_depth_cmdline (Environment& e, const std::string& raw, std::string* err = nullptr) +{ + const std::string tmp = fs::temp_directory_path().generic_string() + "/"; + std::vector args = { "nyxus", "--intDir=" + tmp, "--segDir=" + tmp, "--outDir=" + tmp, + "--features=MEAN", "--filePattern=.*\\.tif", "--outputType=singlecsv", "--coarseGrayDepth=" + raw }; + std::vector argv; + for (auto& a : args) + argv.push_back (a.data()); + testing::internal::CaptureStderr(); + bool ok = e.parse_cmdline ((int) argv.size(), argv.data()); + std::string captured = testing::internal::GetCapturedStderr(); + if (err) + *err = captured; + return ok; +} + +// --coarseGrayDepth takes a depth at every sign +void test_feature_settings_coarse_gray_depth_cli_accepted_mechanics() +{ + for (int depth : { -256, -20, 0, 64, 4096 }) + { + SCOPED_TRACE ("--coarseGrayDepth=" + std::to_string (depth)); + Environment e; + ASSERT_TRUE (parse_coarse_gray_depth_cmdline (e, std::to_string (depth))); + ASSERT_EQ (e.get_coarse_gray_depth(), depth); + } +} + +// The refusal path, and the reason each refusal gives: text that is not one whole integer is no +// integer, while INT_MIN (whose magnitude is no int) and values past the int range are integers out +// of range, refused rather than wrapped into a range they are not in +void test_feature_settings_coarse_gray_depth_cli_refused_mechanics() +{ + for (const char* raw : { "64abc", "abc", "1.5" }) + { + SCOPED_TRACE (std::string ("--coarseGrayDepth=") + raw); + Environment e; + std::string err; + ASSERT_FALSE (parse_coarse_gray_depth_cmdline (e, raw, &err)); + EXPECT_NE (err.find ("expecting an integer constant"), std::string::npos) << err; + } + for (const char* raw : { "-2147483648", "2147483648", "-99999999999", "99999999999" }) + { + SCOPED_TRACE (std::string ("--coarseGrayDepth=") + raw); + Environment e; + std::string err; + ASSERT_FALSE (parse_coarse_gray_depth_cmdline (e, raw, &err)); + EXPECT_NE (err.find ("out of range"), std::string::npos) << err; + } +} + +// The edges of the range parse_grey_depth() checks: an int whose magnitude is an int too. This is a +// type check only; a depth near the edge parses, and whether the buffers it sizes fit is not asked here. +void test_feature_settings_grey_depth_parse_range_mechanics() +{ + for (const char* raw : { "-2147483647", "2147483647", " -20", "+64", "0" }) + { + SCOPED_TRACE (raw); + int v = 12345; + ASSERT_EQ (Nyxus::parse_grey_depth (raw, v), Nyxus::GreyDepthParse::ok); + ASSERT_EQ (v, std::stoi (raw)); + } + for (const char* raw : { "-2147483648", "2147483648", "4294967276", "-99999999999999999999" }) + { + SCOPED_TRACE (raw); + int v = 12345; + ASSERT_EQ (Nyxus::parse_grey_depth (raw, v), Nyxus::GreyDepthParse::out_of_range); + ASSERT_EQ (v, 12345) << "a refused depth must leave the target alone"; + } + for (const char* raw : { "", "abc", "64abc", "1.5", "-" }) + { + SCOPED_TRACE (raw); + int v = 12345; + ASSERT_EQ (Nyxus::parse_grey_depth (raw, v), Nyxus::GreyDepthParse::not_an_integer); + ASSERT_EQ (v, 12345); + } +} + +// Every /greydepth metaparameter applies the CLI's rule. INT_MIN would reach std::abs() as UB, +// and 4294967276 is -20 once wrapped into an int, i.e. 20 PyRadiomics-style bins nobody asked for; both +// are refused and leave the family's depth as it was, and so is text that is no integer. +void test_feature_settings_greydepth_metaparam_refused_mechanics() +{ + Environment e; + e.set_coarse_gray_depth (64); + e.compile_feature_settings(); + + const std::vector>> families = { + { "glcm", [&] { return (int) STNGS_GLCM_GREYDEPTH (e.fsett_GLCM); } }, + { "3glcm", [&] { return (int) STNGS_GLCM_GREYDEPTH (e.fsett_D3_GLCM); } }, + { "3gldm", [&] { return (int) STNGS_GLDM_GREYDEPTH (e.fsett_D3_GLDM); } }, + { "3ngtdm", [&] { return (int) STNGS_NGTDM_GREYDEPTH (e.fsett_D3_NGTDM); } }, + { "3glrlm", [&] { return (int) STNGS_GLRLM_GREYDEPTH (e.fsett_D3_GLRLM); } }, + { "3glszm", [&] { return (int) STNGS_GLSZM_GREYDEPTH (e.fsett_D3_GLSZM); } } }; + + for (const auto& [fam, depth] : families) + { + const int before = depth(); + for (const char* raw : { "-2147483648", "4294967276", "2147483648" }) + { + SCOPED_TRACE (fam + "/greydepth=" + raw); + auto err = e.set_metaparam (fam + "/greydepth=" + raw); + ASSERT_TRUE (err.has_value()); + EXPECT_NE (err->find ("out of range"), std::string::npos) << *err; + ASSERT_EQ (depth(), before); + } + { + SCOPED_TRACE (fam + "/greydepth=abc"); + auto err = e.set_metaparam (fam + "/greydepth=abc"); + ASSERT_TRUE (err.has_value()); + EXPECT_NE (err->find ("expecting an integer"), std::string::npos) << *err; + ASSERT_EQ (depth(), before); + } + // and a depth in range is still taken, at either sign + for (int d : { -20, 32 }) + { + ASSERT_FALSE (e.set_metaparam (fam + "/greydepth=" + std::to_string (d)).has_value()) << fam; + ASSERT_EQ (depth(), d) << fam; + } + } +} \ No newline at end of file diff --git a/tests/test_main_nyxus.h b/tests/test_main_nyxus.h index ac02c2274..41092d6f1 100644 --- a/tests/test_main_nyxus.h +++ b/tests/test_main_nyxus.h @@ -74,6 +74,28 @@ namespace Nyxus } } + /// @brief bench_square12_graded: a 12x12 ROI in a 14x14 frame at levels 100 + 3 ((7x + 11y + xy) + /// mod 37), 36 distinct over 100-208. At 20 PyRadiomics-style bins 14 of its 144 pixels sit + /// exactly on a bin edge (5 at 127, 4 at 154, 5 at 181), and the 5 at 181 are the ones a division + /// by the bin width sends one bin low, so it separates IBSI's fixed bin number from that formula. + /// 2D NGLDM and 2D GLDZM both read it, which is why it lives here rather than in either family's + /// header; tests/vetting/oracles/square12_graded.py builds the same array for MIRP. + static void make_2d_square12_graded_phantom (std::vector& intensity, std::vector& mask) + { + const size_t side = 14, lo = 1, hi = 12; + intensity.clear(); + mask.clear(); + for (size_t y = 0; y < side; y++) + for (size_t x = 0; x < side; x++) + { + const bool in_roi = x >= lo && x <= hi && y >= lo && y <= hi; + const size_t xx = in_roi ? x - lo : 0, yy = in_roi ? y - lo : 0; + const unsigned int level = in_roi ? (unsigned int) (100 + 3 * ((7 * xx + 11 * yy + xx * yy) % 37)) : 0; + intensity.push_back (NyxusPixel {x, y, level}); + mask.push_back (NyxusPixel {x, y, in_roi ? 1u : 0u}); + } + } + static void load_masked_test_roi_data (LR& roidata, const NyxusPixel* intensityData, const NyxusPixel* maskData, size_t count) { // -- mocking phase 1, gatherRoisMetrics(): diff --git a/tests/test_texture_binning_mechanics.h b/tests/test_texture_binning_mechanics.h new file mode 100644 index 000000000..6d5868458 --- /dev/null +++ b/tests/test_texture_binning_mechanics.h @@ -0,0 +1,88 @@ +#pragma once + +// Mechanics of the grey binning every 2D and 3D texture family shares (texture_feature.h). Claims no +// oracle (SPEC 2). + +#include +#include +#include "../src/nyx/features/3d_ooc_volume.h" // bin_roi_3d, and through it texture_feature.h and LR + +// PyRadiomics-style binning divides by the ROI's range, and a ROI of one intensity has a range of zero +// width. That range is one bin: every ROI voxel lands in bin 1, and the background, intensity 0, stays +// at 0. 3D GLCM and 3D NGTDM bin such a ROI, having no constant-ROI intercept before their binning, and +// a negative coarse grey depth sends them here. +void test_texture_binning_zero_width_range_mechanics() +{ + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (7, 7, 7, 8), 1u); + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (7, 7, 7, 1), 1u); + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (0, 7, 7, 8), 0u); + + // through the cube binning the 3D families call, at a negative grey depth + SimpleCube I, D; + I.allocate (3, 2, 2); + I.fill (7); + I.zyx (0, 0, 0) = 0; // one background cell + D.allocate (3, 2, 2); + TextureFeature tf; + tf.bin_intensities_3d (D, I, 7, 7, -8); + EXPECT_EQ (D.zyx (0, 0, 0), 0u); + for (size_t i = 1; i < D.size(); i++) + EXPECT_EQ (D[i], 1u) << "cell " << i; +} + +// The 3D families' in-RAM binning writes each ROI voxel's level at its offset from the box corner and +// leaves every other cell at 0. The box corner is not the origin here, so an offset taken from the +// wrong corner lands a voxel in the wrong cell. The cube takes its shape from the box the voxels are +// checked against, whatever r.aux_image_cube holds: here that is a larger cube, so a binning sized +// from it has 36 cells and a row stride of 4. +void test_texture_binning_roi_cube_places_voxels_mechanics() +{ + LR r; + r.aux_image_cube.allocate (4, 3, 3); + r.aabb.init_x (10); r.aabb.update_x (12); + r.aabb.init_y (20); r.aabb.update_y (21); + r.aabb.init_z (5); r.aabb.update_z (6); + r.raw_pixels_3D = { Pixel3 (10, 20, 5, 1), Pixel3 (12, 21, 6, 64), Pixel3 (11, 20, 6, 33) }; + r.aux_min = 1; + r.aux_max = 64; + + SimpleCube D; + Nyxus::bin_roi_3d (D, r, 4); // MATLAB, 4 levels over [0, 64]: floor(4 x / 64 + 1), clipped to 4 + ASSERT_EQ (D.size(), 12u); + ASSERT_EQ (D.width(), 3); + ASSERT_EQ (D.height(), 2); + ASSERT_EQ (D.depth(), 2); + EXPECT_EQ (D.zyx (0, 0, 0), 1u); + EXPECT_EQ (D.zyx (1, 1, 2), 4u); + EXPECT_EQ (D.zyx (1, 0, 1), 3u); + size_t background = 0; + for (auto v : D) + background += (v == 0); + EXPECT_EQ (background, 9u); +} + +// The refusal path: a voxel outside the box has no cell in the cube, and is refused rather than +// written past it +void test_texture_binning_roi_cube_refuses_voxel_outside_box_mechanics() +{ + LR r; + r.aux_image_cube.allocate (3, 2, 2); + r.aabb.init_x (10); r.aabb.update_x (12); + r.aabb.init_y (20); r.aabb.update_y (21); + r.aabb.init_z (5); r.aabb.update_z (6); + r.raw_pixels_3D = { Pixel3 (10, 20, 5, 1), Pixel3 (13, 20, 5, 9) }; // x = 13 is one past the box + r.aux_min = 1; + r.aux_max = 9; + + SimpleCube D; + EXPECT_THROW (Nyxus::bin_roi_3d (D, r, 4), std::out_of_range); +} + +// Negative case: a range of nonzero width still bins by IBSI's fixed bin number, +// floor(n (x - min) / (max - min)) + 1, the top level clipped into bin n. +void test_texture_binning_nonzero_range_unchanged_mechanics() +{ + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (1, 1, 8, 8), 1u); + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (4, 1, 8, 8), 4u); // floor(8 * 3 / 7) + 1 + EXPECT_EQ (TextureFeature::to_grayscale_radiomix (8, 1, 8, 8), 8u); +} diff --git a/tests/vetting/TOOLS.md b/tests/vetting/TOOLS.md index 823cee635..bb2fefb11 100644 --- a/tests/vetting/TOOLS.md +++ b/tests/vetting/TOOLS.md @@ -114,7 +114,8 @@ Gotchas hit while doing it: - **PyRadiomics' `binCount` maps to the Nyxus setting of the family being matched, not the generic one.** The 3D texture calculators bin on `GLCM_GREYDEPTH` / `GLRLM_GREYDEPTH` / ... and ignore `GREYDEPTH` entirely; a negative value activates radiomics binCount-based binning, so - `binCount: 20` is `_GREYDEPTH = -20`. Left unset the per-family setting defaults to 0, + `binCount: 20` is `_GREYDEPTH = -20`. Left unset in a settings vector a test builds by hand, + the per-family setting is 0, which means **no binning at all** rather than a default depth - the features then run on raw intensities and are silently off by orders of magnitude, not by a few percent. A grey-level emphasis feature far above what the bin count allows (3D GLRLM `HGLRE` at 4.3e6 against a ~4e3 diff --git a/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md index 2db23a802..fba162041 100644 --- a/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md @@ -215,11 +215,10 @@ values reproduce PyRadiomics **to the last bit** on all seven dependence-axis fe (`SDE` 0.0066408036122542298, `LDE` 239.41666666666666, `DN` 15.333333333333334, `DNN` 0.31944444444444442, `DV` 26.743055555555554, `GLN` 48, `GLV` 0), with `3GLDM_DE` at the family's documented `fast_log10` residual and the grey-level features apart only by the level convention. -So nothing under the intercept is wrong; the intercept is the whole defect. Run at *radiomics* -binning instead, the same bypass leaves the case green: `to_grayscale_radiomix()`'s -`binW = (max - min) / binCount` is zero at zero range, every voxel bins to background and the -`Nz == 0` branch emits the same sentinel by a second route — which is why the cell is asserted at the -configuration where the intercept stands alone. +So nothing under the intercept is wrong; the intercept is the whole defect. At *radiomics* binning +`to_grayscale_radiomix()` puts a range of zero width into one bin, so beneath the intercept every voxel +is level 1 there too; the cell is asserted at no binning, the configuration the bypass was measured +at. K–N are the registry-side controls. K is the defect the review found: before this round the per-feature rows named `TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS`, a case that asserts dependence cells @@ -262,8 +261,8 @@ this report for why and for what fixture would. NGLDM as *separate* families with different conventions, so a `mirp` run would need its own reconciliation before it could corroborate anything here. - **`GLDM_GREYDEPTH = 0` / `IBSI=true` are pinned but unvetted.** They are the same code path reached - two ways, and it is the **compiled default** — `compile_feature_settings()` names no default for - `GLDM_GREYDEPTH`, so the zero-fill stands and only `--3gldm/greydepth=N` moves it. All fourteen are + two ways, and it is the **no-binning production point** — `--coarseGrayDepth=0` or + `3gldm/greydepth=0` selects it; a run that names neither bins at the coarse grey depth, 64. All fourteen are now snapshotted at that configuration (`gldm3d.regression_ut_phantom_nobinning`), which claims no vetting: the oracle question, whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume, is still open. See `matrix/gldm3d.md`. diff --git a/tests/vetting/audit/glrlm_3d_golden_regen.md b/tests/vetting/audit/glrlm_3d_golden_regen.md index 2a8129e41..3b3c7e42b 100644 --- a/tests/vetting/audit/glrlm_3d_golden_regen.md +++ b/tests/vetting/audit/glrlm_3d_golden_regen.md @@ -86,11 +86,9 @@ own profile, so a table and its assertions cannot drift apart. Sanity checks worth running on any regenerated set, both of which the pre-2026-08 goldens failed: - `SRE`, `RP`, `GLNN` and `RLNN` are bounded in **[0,1]** and `LRE` is **≥ 1**. A value outside those - is a broken golden — or, for `RP` at positive grey depths, the open implementation defect recorded - in `glrlm_3d_pyradiomics_vetting_report.md`. That is why the `glrlm3d.regression_ut_phantom` - benchmark uses binCount binning and not a positive `GLRLM_GREYDEPTH`. The grey64 table below is the - one deliberate exception and it does trip this check — 4 of `RP`'s 13 angles read 1.0231 — which is - the filed defect showing through, not a broken golden. + is a broken golden. `TEST_3D_GLRLM_BOUNDED_FEATURES_INVARIANT` asserts the five bounds on all 13 + directions of the same phantom across binCount, unbinned and MATLAB grey depths, so a regenerated + table that broke one would already have failed it. - The magnitudes must be consistent with the bin count. Unbinned, `HGLRE` reaches 4.3e6; at 64 grey levels the ceiling is ~4e3. An `HGLRE` in the millions means `GLRLM_GREYDEPTH` was never set. @@ -100,6 +98,12 @@ Recipe `glrlm3d.regression_ut_phantom_grey64`: the same segmented phantom at `GL which `bin_intensities_3d()` routes through `matlab_grey_binning` — a fixed 64-level count — instead of the binCount binning derived from the ROI's own min/max. +The ROI does not fill its bounding box, and MATLAB binning sends intensity 0 to level 1, so at this +recipe what counts as background decides every value: the family takes it from the ROI's voxel cloud +and gives it level 0, at which no run is counted. The table was regenerated on that code, and that is +why its 16 means differ from the retired sweep's literals described below, which counted the +background's runs at level 1 and put `RP` above 1 on 4 of the 13 angles. + It pins **every slot of all 32 features**: the 13 angled values of each base feature and the single mean its `*_AVE` twin stores. The family's retired coverage sweep pinned only the 16 means, and `revet.txt` §9's first rule is why that is not enough — two per-angle errors of opposite sign leave @@ -126,9 +130,8 @@ Checks run mechanically over the whole table rather than spot-checked (`revet.tx | check | result | |---|---| -| every `*_AVE` pin == arithmetic mean of its own 13 per-angle pins | worst `rel=2.9e-16` (`LRLGLE_AVE`), passes at `rel=1e-12` | -| `SRE`, `GLNN`, `RLNN` ∈ [0,1] over all 13 angles and the mean | pass | -| `RP` ∈ [0,1] | **fails on 4 of 13 angles** (1.0231) — the filed defect, see below | +| every `*_AVE` pin == arithmetic mean of its own 13 per-angle pins | worst `rel=1.5e-16` (`RLN_AVE`), passes at `rel=1e-12` | +| `SRE`, `GLNN`, `RLNN`, `RP` ∈ [0,1] over all 13 angles and the mean | pass | | `LRE` ≥ 1 | pass | | `RE`, `GLV`, `RV` ≥ 0 | pass | diff --git a/tests/vetting/audit/glrlm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/glrlm_3d_pyradiomics_vetting_report.md index 1895681d0..1c0809414 100644 --- a/tests/vetting/audit/glrlm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/glrlm_3d_pyradiomics_vetting_report.md @@ -190,44 +190,36 @@ base assertions compare every direction; the `*_AVE` assertions keep the directi still read the stored feature. Planted-defect check: a 1e-5 relative error in a single direction of a single feature fails the base assertion, where the averaged form passed it. -## `3GLRLM_RP` leaves its mathematical bound — filed, not fixed here +## `3GLRLM_RP` and the other bounded features, across every binning -Run Percentage is runs / voxels and cannot exceed 1. On the `ut_` segmented phantom, averaged over -the 13 angles, it does: +Run Percentage is runs / voxels and lies in [0, 1]; `SRE`, `RLNN` and `GLNN` do too, and `LRE` is at +least 1. On the `ut_` segmented phantom, averaged over the 13 angles: | `GLRLM_GREYDEPTH` | `RP` | `SRE` | `RLNN` | `GLNN` | `LRE` | |---|---|---|---|---|---| | −20 (binCount 20) | 0.703 | 0.841 | 0.676 | 0.052 | 4.73 | | −100 (binCount 100) | 0.917 | 0.961 | 0.907 | 0.010 | 1.59 | | 0 (unbinned) | 0.990 | 0.994 | 0.986 | 0.0006 | 1.04 | -| 32 | 0.819 | 0.766 | 0.556 | 0.052 | 33.5 | -| 64 | 0.940 | 0.846 | 0.688 | 0.030 | 27.0 | -| 100 | 0.987 | 0.872 | 0.736 | 0.023 | 25.0 | -| 128 | **1.007** | 0.882 | 0.757 | 0.020 | 24.3 | -| 256 | **1.045** | 0.901 | 0.794 | 0.014 | 23.0 | - -It grows monotonically with the bin count and crosses 1 at positive grey depths ≥ 128 for the -13-angle average (≥ 64 for a single angle). Every other bounded feature in the family stays in range -across the whole sweep, so this is specific to `RP`. More runs than voxels is impossible, and the -monotone growth points at a denominator that does not track the binning. - -The per-angle figure is now pinned rather than described. At `GLRLM_GREYDEPTH=+64`, -`glrlm_3d_regression_grey64_ref_vals` records **4 of the 13 angles at 1.0231204815764925** — angles -0, 2, 6 and 8 — against a 13-angle average of 0.9400989344144661. The average is what the table used -to hold on its own, and it is in range, which is precisely why an aggregate-only pin could not have -shown this. - -**Not fixed here** — it is a behaviour change in a public feature and belongs on its own branch, -alongside a cheap invariant test (`RP ≤ 1`, `SRE ≤ 1`, `LRE ≥ 1`) so the class of defect cannot return -silently. That check is what found this one. - -Both of this branch's benchmarks use binCount binning, where `RP` is in range, and the -`3GLRLM_RP_AVE` registry row says so explicitly rather than claiming the feature holds at every -config. A third benchmark joined the file when the family's coverage sweep was retired — the grey64 -table in `test_3d_glrlm_regression.h`, at `GLRLM_GREYDEPTH=+64` — and because it pins per angle -rather than only the mean, it is the first artifact in the tree that carries the out-of-bound values -themselves. They are pinned as a drift guard with a comment naming this section, not endorsed: the -fix will show up as a diff on four numbers instead of as a silent change. +| 32 | 0.721 | 0.845 | 0.682 | 0.048 | 4.08 | +| 64 | 0.842 | 0.923 | 0.824 | 0.024 | 2.35 | +| 100 | 0.890 | 0.947 | 0.875 | 0.015 | 1.84 | +| 128 | 0.909 | 0.957 | 0.898 | 0.012 | 1.66 | +| 256 | 0.948 | 0.974 | 0.937 | 0.006 | 1.32 | + +Every value is in range, and at positive grey depths the five move with the bin count the way they +do under binCount binning. The ROI does not fill its bounding box, and MATLAB binning (a positive +grey depth) sends intensity 0 to level 1, the level the ROI's darkest voxels carry; the family takes +the background from the ROI's voxel cloud instead and gives it level 0, at which no run is counted. +Counted at level 1, the background's runs put `RP` above 1 on 4 of the 13 angles at +64 (1.0231) and +on the 13-angle average from +128 up, and pushed `LRE` to 23–34. + +`test_3d_glrlm_bounded_features_invariant` asserts all five bounds on every one of the 13 angles of +this phantom, at −100, −20, 0, 32, 64, 128 and 256. It checks per angle because the average can stay +in range while single angles leave it, which is what an aggregate-only pin could not have shown. + +Both of this branch's benchmarks use binCount binning. A third joined the file when the family's +coverage sweep was retired: the grey64 table in `test_3d_glrlm_regression.h`, at +`GLRLM_GREYDEPTH=+64`, pinned per angle. ## Include hygiene and file-level observations diff --git a/tests/vetting/audit/glszm_3d_golden_regen.md b/tests/vetting/audit/glszm_3d_golden_regen.md index 2ec10a59c..0598f79d4 100644 --- a/tests/vetting/audit/glszm_3d_golden_regen.md +++ b/tests/vetting/audit/glszm_3d_golden_regen.md @@ -129,8 +129,8 @@ at.** Zero is a third configuration — no binning rather than 64 MATLAB levels by up to five orders of magnitude between the two. The second recipe is the same phantom at `GLSZM_GREYDEPTH=0` — `make_glszm3d_settings(64, 0)` — which -is what a run passing no `--3glszm/greydepth` reaches the feature with. Its sixteen pins share one -gtest case, `TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION`, because one phantom read answers all +is what `--coarseGrayDepth=0` or `3glszm/greydepth=0` selects: no binning. Its sixteen pins share one +gtest case, `TEST_3D_GLSZM_NO_BINNING_REGRESSION`, because one phantom read answers all sixteen and the matrix at this setting is 3024 grey levels wide. `TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION` sits beside them and needs no phantom at all: it pins the soft-NaN sentinel a constant-intensity ROI comes back as, which is a divergence rather than a value diff --git a/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md index a4e60df46..6bba3677c 100644 --- a/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md @@ -241,14 +241,14 @@ That is why `matrix/glszm3d.md` now carries one cell for the two rows rather tha ## The `GLSZM_GREYDEPTH == 0` cell -This is the value a run passing no `--3glszm/greydepth` reaches the feature with: -`compile_feature_settings()` zero-fills the family's settings vector and nothing writes the entry. -The first pass added `test_3d_glszm_default_greydepth_mechanics`, which asserts that the 0 really -arrives and that the sixteen features are finite there. Finiteness is mechanics; it says nothing +This is the no-binning configuration, which `--coarseGrayDepth=0` or `3glszm/greydepth=0` +selects; a run that names neither bins at the coarse grey depth, 64. +`test_3d_glszm_default_greydepth_mechanics` asserts that the default depth really arrives and +that the sixteen features are finite there. Finiteness is mechanics; it says nothing about the numbers. `glszm3d.regression_ut_phantom_nobinning` pins them: sixteen `%.17g` goldens on `bench_ut57_3d` under -one case, `TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION`. One case for the sixteen because one phantom +one case, `TEST_3D_GLSZM_NO_BINNING_REGRESSION`. One case for the sixteen because one phantom read answers all of them, and the matrix at this setting is 3024 grey levels wide against `binCount`'s 20. They claim no oracle: PyRadiomics discretises before it counts zones and has no counterpart for reading 2001 raw levels off this phantom. The *setting* is vetted on the fixture that is small enough @@ -271,8 +271,8 @@ with a single populated cell and sixteen finite features over it. On a 2×2×2 b that is `SAE = 1/64`, `LAE = 64`, `ZE = 0`, `GLV = 0`, `ZP = 1/8`. Nyxus returns the soft-NaN sentinel — `--noval`, default `0.0` — for all sixteen. -The guard is doing real work at radiomics binning, where `to_grayscale_radiomix` divides by -`(max - min)`; it is unconditional, so it discards the two schemes that would have answered as well. +The guard is unconditional, so it discards every scheme's answer, radiomics binning's included: +`to_grayscale_radiomix` puts a range of zero width into one bin. Negative control O makes one voxel of the constant block different, so the intercept does not fire, and the family computes `SAE = 0.51020408163265307` on the result — the arithmetic is there, it is the guard that is too wide. @@ -327,11 +327,12 @@ the code rather than of a recipe that got lost. They are replaced with a fresh ` `glszm3d.regression_ut_phantom` — `GREYDEPTH=64`, `IBSI=false`, `GLSZM_GREYDEPTH=64`, the configuration the retired 3D coverage sweep ran every 3D family at on this same phantom. -`GLSZM_GREYDEPTH=0` is not degenerate, and that is the difference from `NGTDM_RADIUS=0`: it is this -family's documented "no binning" default, `--3glszm/greydepth` is what overrides it, and a run that -passes no such flag produces finite values for all sixteen features. -`test_3d_glszm_default_greydepth_mechanics` asserts exactly that, so **no `src/` change is proposed -by this branch**. +`GLSZM_GREYDEPTH=0` is not degenerate, and that is the difference from `NGTDM_RADIUS=0`: it is the +no-binning setting, which `--coarseGrayDepth=0` or `3glszm/greydepth=0` selects, and it produces +finite values for all sixteen features; `glszm3d.regression_ut_phantom_nobinning` pins them. A run +that passes neither flag bins at the coarse grey depth, 64, and +`test_3d_glszm_default_greydepth_mechanics` asserts that it reaches the feature at that depth with +settings that produce numbers. --- diff --git a/tests/vetting/audit/scan_gldzm3d_coverage.py b/tests/vetting/audit/scan_gldzm3d_coverage.py index cc25a560d..ce9a97084 100644 --- a/tests/vetting/audit/scan_gldzm3d_coverage.py +++ b/tests/vetting/audit/scan_gldzm3d_coverage.py @@ -37,6 +37,7 @@ "gldzm3d.mirp_compat_phantom_radiomics": re.compile( r"^test_3d_gldzm_[a-z0-9]+_radiomics_(mirp|regression)$"), "gldzm3d.regression_ut_phantom": re.compile(r"^test_3d_gldzm_[a-z0-9]+_regression$"), + "gldzm3d.mirp_fbn20_negdepth": re.compile(r"^test_3d_gldzm_negative_greydepth_mirp$"), } FAMILY = scanlib.Family( @@ -47,6 +48,7 @@ # comparison measures is the GLDZM rather than the binning the two disagree about on a CT-like # fixture (audit/gldzm_3d_mirp_vetting_report.md). oracle_suffix={"mirp": "mirp"}, + table_owner={"gldzm_3d_mirp_negdepth_ref_vals": "test_3d_gldzm_negative_greydepth_mirp"}, notes=NOTE, enum_dim_prefix=True, other_note="asserted", diff --git a/tests/vetting/audit/scan_gldzm_coverage.py b/tests/vetting/audit/scan_gldzm_coverage.py index b5ee37536..357c0a62b 100644 --- a/tests/vetting/audit/scan_gldzm_coverage.py +++ b/tests/vetting/audit/scan_gldzm_coverage.py @@ -36,6 +36,7 @@ dim="2D", family="gldzm", sources=SOURCES, oracle_suffix={"mirp": "mirp", "ibsi": "ibsi"}, + table_owner={"gldzm_2d_mirp_negdepth_ref_vals": "test_2d_gldzm_negative_greydepth_mirp"}, notes=scanlib.dual_oracle_notes(NOTE, DUAL_ORACLE), ) diff --git a/tests/vetting/audit/scan_glrlm3d_coverage.py b/tests/vetting/audit/scan_glrlm3d_coverage.py index 5bdee4b89..145897c5b 100644 --- a/tests/vetting/audit/scan_glrlm3d_coverage.py +++ b/tests/vetting/audit/scan_glrlm3d_coverage.py @@ -19,8 +19,6 @@ ] NOTE = { - "3GLRLM_RP": "exceeds its mathematical bound of 1 at positive GLRLM_GREYDEPTH values; in range " - "at the binCount binning both tests use", "3GLRLM_RP_AVE": "registry read oracle=mirp while the base row read oracle=pyradiomics for the " "same quantity; no mirp run for 3D GLRLM has ever existed in the tree", "3GLRLM_RE": "the family's only sum over logarithms; fast_log10 puts it 3.9e-4 from " diff --git a/tests/vetting/audit/scan_glszm3d_coverage.py b/tests/vetting/audit/scan_glszm3d_coverage.py index feb468921..a137a536c 100644 --- a/tests/vetting/audit/scan_glszm3d_coverage.py +++ b/tests/vetting/audit/scan_glszm3d_coverage.py @@ -33,7 +33,7 @@ # by grey level rather than by feature and cover no feature at all. TABLE_OWNER = { "glszm_3d_pyradiomics_gapped_ref_vals": "test_3d_glszm_ibsi_gapped_pyradiomics", - "glszm_3d_regression_nobinning_ref_vals": "test_3d_glszm_default_greydepth_regression", + "glszm_3d_regression_nobinning_ref_vals": "test_3d_glszm_no_binning_regression", } ORACLE_SUFFIX = {"pyradiomics": "pyradiomics"} @@ -48,7 +48,7 @@ "glszm3d.pyradiomics_ibsi_gapped": re.compile(r"^test_3d_glszm_ibsi_gapped_pyradiomics$"), "glszm3d.regression_ut_phantom": re.compile(r"^test_3d_glszm_[a-z0-9]+_regression$"), "glszm3d.regression_ut_phantom_nobinning": - re.compile(r"^test_3d_glszm_default_greydepth_regression$"), + re.compile(r"^test_3d_glszm_no_binning_regression$"), "glszm3d.regression_constant_roi": re.compile(r"^test_3d_glszm_constant_roi_regression$"), } diff --git a/tests/vetting/audit/scan_ngldm3d_coverage.py b/tests/vetting/audit/scan_ngldm3d_coverage.py index ace7e3b2b..d5723c202 100644 --- a/tests/vetting/audit/scan_ngldm3d_coverage.py +++ b/tests/vetting/audit/scan_ngldm3d_coverage.py @@ -13,6 +13,7 @@ import scanlib SOURCES = [ + "test_3d_ngldm_mechanics.h", "test_3d_ngldm_mirp.h", "test_3d_ngldm_regression.h", os.path.join("python", "test_nyxus.py"), @@ -33,6 +34,7 @@ # features carry a vetted row there; 3NGLDM_DCP is a non-discriminating agreement and # 3NGLDM_GLM / 3NGLDM_DCM have no MIRP counterpart, so those three stay regression-only. oracle_suffix={"mirp": "mirp"}, + table_owner={"ngldm_3d_mirp_negdepth_ref_vals": "test_3d_ngldm_negative_greydepth_mirp"}, notes=NOTE, enum_dim_prefix=True, enum_alias="NGLDM", diff --git a/tests/vetting/audit/scan_ngldm_coverage.py b/tests/vetting/audit/scan_ngldm_coverage.py index af99b9bf6..f8870a13b 100644 --- a/tests/vetting/audit/scan_ngldm_coverage.py +++ b/tests/vetting/audit/scan_ngldm_coverage.py @@ -13,6 +13,7 @@ SOURCES = [ "test_2d_ngldm_ibsi.h", + "test_2d_ngldm_mechanics.h", "test_2d_ngldm_mirp.h", "test_2d_ngldm_regression.h", ] @@ -34,6 +35,7 @@ dim="2D", family="ngldm", sources=SOURCES, oracle_suffix={"mirp": "mirp", "ibsi": "ibsi"}, + table_owner={"ngldm_2d_mirp_negdepth_ref_vals": "test_2d_ngldm_negative_greydepth_mirp"}, notes=scanlib.dual_oracle_notes(NOTE, DUAL_ORACLE), ) diff --git a/tests/vetting/benchmarks.md b/tests/vetting/benchmarks.md index 819f5b74a..8f78bd189 100644 --- a/tests/vetting/benchmarks.md +++ b/tests/vetting/benchmarks.md @@ -316,6 +316,26 @@ goldens' meaning — see `audit/gabor_2d_skimage_vetting_report.md` §4.1. --- +## `bench_square12_graded` — a 12x12 ROI whose levels land on bin edges + +| | | +|---|---| +| Data | `Nyxus::make_2d_square12_graded_phantom()` in `tests/test_main_nyxus.h` | +| ROI | the 12x12 interior of a 14x14 frame, at levels `100 + 3 ((7x + 11y + xy) mod 37)` | +| Shape | 36 distinct levels over 100-208; at 20 PyRadiomics-style bins (range 108, bin width 5.4) the interior bin edges fall at 127, 154 and 181, and 14 of the 144 pixels sit exactly on one: 5 at 127, 4 at 154, 5 at 181 | +| Why it exists | the smallest fixture that separates IBSI's fixed bin number, `floor(n (x - min) / (max - min)) + 1`, from a formula that divides by the bin width, `floor((x - min) / ((max - min) / n)) + 1`: the 5 pixels at 181 are the ones that division sends one bin low, while it gets 127 and 154 right. The IBSI phantom has six levels, which 20 bins leave where they are, and the segmented 3D phantom (`bench_ut57_3d`) has 2736 ROI voxels on a bin edge at 20 bins but an exact bin width of 100, so neither can show this | + +Recipes: `ngldm.mirp_fbn20_negdepth`, `gldzm.mirp_fbn20_negdepth`. + +Tests reaching it today: `test_2d_ngldm_mirp.h`, `test_2d_ngldm_mechanics.h`, `test_2d_gldzm_mirp.h`. + +It lives in `test_main_nyxus.h` because two families read it (SPEC 6.3.1). +`oracles/square12_graded.py` builds the same array for MIRP, and `oracles/gen_ngldm_mirp.py` and +`oracles/gen_gldzm_mirp.py` both load it from there; each of them compares the formula in the header +with its own on every run, `--check` included. It fills its bounding box, so a GLDZM zone's border distance on +it is the distance to the frame -- which is why 2D GLDZM pins only its six features that read none. + +--- ## `bench_scene7_5roi_enclosed` — five labelled ROIs in one 7×7 scene | | | diff --git a/tests/vetting/check_test_names.py b/tests/vetting/check_test_names.py index bdc794521..cd0d499e0 100644 --- a/tests/vetting/check_test_names.py +++ b/tests/vetting/check_test_names.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3 """Enforce the SPEC.md 6.1/6.2 test-naming conventions over the test tree. Two rules, both mechanical: @@ -85,9 +85,12 @@ "readers and accumulators shared by both dims - a TIFF sample type and a value histogram", "test_cli_mechanics.py": "the CLI's exit-status contract, asserted on a 2D whole-slide run and a 3D one", + "test_coarse_gray_depth_mechanics.py": + "the coarse grey depth every 2D and 3D texture family starts from, asserted in both dims", "test_feature_calculation_common.h": "the assert_feature template, used from both dims", "test_buffer_from_cloud_mechanics.h": "the 2D and 3D cloud-to-buffer writers and the AABB they check against, asserted side by side", + "test_texture_binning_mechanics.h": "the grey-binning helpers every 2D and 3D texture family shares", "test_vetting_mechanics.py": "self-test of check_coverage.py / check_test_names.py", "test_environment_lifecycle_mechanics.py": "instance -> Environment binding in the bindings; no image dimensionality involved", diff --git a/tests/vetting/config_recipes.md b/tests/vetting/config_recipes.md index 0214fda69..bd22c4885 100644 --- a/tests/vetting/config_recipes.md +++ b/tests/vetting/config_recipes.md @@ -389,6 +389,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `GLDZM_SDLGLE` and `GLDZM_ZDV` are in the recipe but covered by mirp only — the IBSI file never held a published value for either. +## gldzm.mirp_fbn20_negdepth +- `bench_square12_graded` (`test_main_nyxus.h`) at `IBSI=false`, `GREYDEPTH=-20`: the ROI binned into + 20 PyRadiomics-style bins over the ROI's own [min, max], IBSI's fixed bin number + `floor(20 (x - min) / (max - min)) + 1`. Oracle: `mirp` 2.6.0 with + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=20` -- each tool + discretises for itself, so the binning is part of what is compared, not an input to it. Generator: + `oracles/gen_gldzm_mirp.py`, with the square from `oracles/square12_graded.py` (`--check` + re-verifies every pin). +- mirp runs `by_slice=True`. Used by `test_2d_gldzm_negative_greydepth_mirp` in `test_2d_gldzm_mirp.h`, + at `rel=1e-9` (measured worst residual 6.2e-16). +- **The fixture is what makes the edge visible.** 14 of the square's 144 pixels sit exactly on a bin + edge at 20 bins (`20 (x - min)` a multiple of the range): 5 at 127, 4 at 154, 5 at 181. The 5 at + 181 are the ones a division by the bin width sends one bin low; PyRadiomics' `histogram`/`digitize` + and MIRP put all 14 in the bin above their edge. +- **Six features, not sixteen.** The square fills its bounding box, so a zone's border distance cannot + tell the 2D distance map from IBSI's -- they part on a ROI with background inside it. Only the six + features that read no border distance are pinned: `GLNU`, `GLNUN`, `ZP`, `GLV`, `LGLZE`, `HGLZE`. + ## ngldm.ibsi_phantom_2d - The four IBSI digital-phantom slices (`ibsi_phantom_z1..z4`, `test_data.h`), each featurised on its own with `IBSI=true` and `GREYDEPTH=128`, and the per-feature values averaged over the four. @@ -405,6 +423,21 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g - `NGLDM_GLM` and `NGLDM_DCM` are outside this recipe: they are Nyxus mean-style rows with no IBSI NGLDM counterpart and no mirp column, so they stay `regression` in `test_2d_ngldm_regression.h`. +## ngldm.mirp_fbn20_negdepth +- `bench_square12_graded` (`test_main_nyxus.h`) at `IBSI=false`, `GREYDEPTH=-20`: the ROI binned into + 20 PyRadiomics-style bins over the ROI's own [min, max], IBSI's fixed bin number + `floor(20 (x - min) / (max - min)) + 1`. Oracle: `mirp` 2.6.0 with + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=20` -- each tool + discretises for itself, so the binning is part of what is compared, not an input to it. Generator: + `oracles/gen_ngldm_mirp.py`, with the square from `oracles/square12_graded.py` (`--check` + re-verifies every pin). +- mirp runs `by_slice=True`, distance 1, difference level 0. Used by + `test_2d_ngldm_negative_greydepth_mirp` in `test_2d_ngldm_mirp.h`, at `rel=1e-9` and `rel=1e-6` for + `NGLDM_DCENT` (measured worst residual 2.1e-16). `NGLDM_DCP` is left out as at the phantom recipe. +- 14 of the square's 144 pixels sit exactly on a bin edge at 20 bins, and the 5 at 181 are the ones a + division by the bin width sends one bin low. `test_2d_ngldm_zero_greydepth_equals_ibsi_mechanics` + holds the same fixture to its other sign: at `GREYDEPTH=0` the family reads the raw levels, as IBSI does. + ## glszm.ibsi_phantom_2d - The four IBSI digital-phantom slices (`ibsi_phantom_z1..z4`, `test_data.h`, benchmark `ibsi_digital_phantom`), each featurised on its own with `IBSI=true` and `GREYDEPTH=128`, and the @@ -690,9 +723,8 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `GREYDEPTH=100`, `IBSI=false`, `GLRLM_GREYDEPTH=-20` (binCount 20), averaged over the 13 3D angles. **No oracle** — these are Nyxus' own values, pinned as drift guards in `test_3d_glrlm_regression.h` and regenerated by `test_3d_glrlm_dump_regression()`. -- Same grey binning as `glrlm3d.pyradiomics_bincount20`, on a different fixture. Positive - `GLRLM_GREYDEPTH` values are deliberately avoided here: `3GLRLM_RP` leaves its [0,1] bound at - those settings (`audit/glrlm_3d_pyradiomics_vetting_report.md`). +- Same grey binning as `glrlm3d.pyradiomics_bincount20`, on a different fixture. The positive + `GLRLM_GREYDEPTH` profile of the same phantom is `glrlm3d.regression_ut_phantom_grey64` below. ## glrlm3d.regression_ut_phantom_grey64 - The same segmented phantom and Nyxus settings as `glrlm3d.regression_ut_phantom` except @@ -760,6 +792,23 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g the ROI masking on a 2001-wide ladder rather than a 44-wide one. `3NGLDM_DCP` is excluded here for the same reason as at the other recipes: MIRP returns `ngl_dc_perc` = 1.0 at this config too. +## ngldm3d.mirp_fbn20_negdepth +- The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `IBSI=false`, + `GREYDEPTH=-20`: the ROI binned into + 20 PyRadiomics-style bins over the ROI's own [min, max], IBSI's fixed bin number + `floor(20 (x - min) / (max - min)) + 1`. Oracle: `mirp` 2.6.0 with + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=20` -- each tool + discretises for itself, so the binning is part of what is compared, not an input to it. Generator: + `oracles/gen_ngldm3d_mirp.py` (`--check` re-verifies every pin). +- MIRP runs `by_slice=False`, distance 1, alpha 0, on the integer levels Nyxus loads the float phantom + as (`nyxus_raw_levels()`: the loader's shift, not a binning step). Used by + `test_3d_ngldm_negative_greydepth_mirp` in `test_3d_ngldm_mirp.h`, at `rel=1e-9` and `rel=1e-6` for + `3NGLDM_DCENT` (measured worst residual 5.1e-16). +- **The config point where the binning itself is compared.** `ngldm3d.mirp_samelevels` hands MIRP the + levels Nyxus bins to and so judges nothing of the binning; here MIRP bins for itself. + `test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics` holds the family to the other sign: at + `GREYDEPTH=0` it reads the raw levels, as `ngldm3d.mirp_ibsi_rawlevels` does. + ## gldzm3d.mirp_compat_phantom - The GLDZM compatibility phantom (`compat_int/compat_int_gldzm_3d.nii` + `compat_seg/compat_seg_gldzm_3d.nii`, label 57) at `IBSI=true`, which switches the family's @@ -823,6 +872,20 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g establishes is that the agreement at `gldzm3d.mirp_compat_phantom` is not an artifact of that phantom's size: on a 274,432-voxel ROI the worst residual is rel=1.0e-14. +## gldzm3d.mirp_fbn20_negdepth +- The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `IBSI=false`, + `GREYDEPTH=-20`: the ROI binned into + 20 PyRadiomics-style bins over the ROI's own [min, max], IBSI's fixed bin number + `floor(20 (x - min) / (max - min)) + 1`. Oracle: `mirp` 2.6.0 with + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=20` -- each tool + discretises for itself, so the binning is part of what is compared, not an input to it. Generator: + `oracles/gen_gldzm3d_mirp.py` (`--check` re-verifies every pin). +- MIRP runs `by_slice=False` on the integer levels Nyxus loads the float phantom as. Used by + `test_3d_gldzm_negative_greydepth_mirp` in `test_3d_gldzm_mirp.h`, at `rel=1e-9` and `rel=1e-6` for + `3GLDZM_ZDE` (measured worst residual 2.4e-16, 4.1e-15 on `ZDE`). +- **The radiomics scheme where it re-bins.** `gldzm3d.mirp_compat_phantom_radiomics` runs the same + scheme at a bin count that is the identity on its fixture; here 2001 levels fold into 20. + ## ngtdm3d.pyradiomics_binwidth1 - The 4x4x3 NGTDM phantom (`compat_int/compat_int_ngtdm_3d.nii` + `compat_seg/compat_seg_ngtdm_3d.nii`, label 57) at `GREYDEPTH=100`, `IBSI=false`, @@ -889,7 +952,7 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g levels. - **The two binning schemes coincide by construction, not by luck.** PyRadiomics' `binCount` lays `binCount` uniform edges over the ROI's own min..max and digitises to 1..N; - `to_grayscale_radiomix` computes `(x - min) / ((max - min) / binCount) + 1` and clamps the top bin, + `to_grayscale_radiomix` computes `floor(binCount (x - min) / (max - min)) + 1` and clamps the top bin, which is the same partition. Both sides then gather zones over the full 26-voxel neighbourhood. That is what makes `rel=1e-9` honest on a cross-tool comparison: fifteen of the sixteen features agree to the last bit. @@ -950,24 +1013,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g in a different last bits there. Measured on this same phantom, `3GLRLM_RE` moves by **1.06e-9** between macOS-arm64 and Windows while every non-logarithm feature moves by ~1e-16 — which is why `test_3d_glrlm_regression.h` carries the identical carve-out, at the same `1e6`. -- `GLSZM_GREYDEPTH=64` makes bin 1 the background level, so a voxel binned there starts no zone of - its own. That is a different quantity from `glszm3d.pyradiomics_bincount20`, where nothing is - background, which is why this fixture carries no oracle claim. -- Every recipe here states `GLSZM_GREYDEPTH` explicitly rather than leaning on the zero a settings - vector starts at. Zero is this family's documented "no binning" default and it does produce - numbers, but it is a third configuration again: the unwired version of - `test_3d_glszm_regression.h` left it there, and at that setting every one of its sixteen pins is - wrong by between 1.6x and 1.5e6x. It has a recipe of its own below. +- Under `GLSZM_GREYDEPTH=64` the background is level 0 and starts no zone, and every ROI voxel, level 1 + included, starts zones of its own level. 64 MATLAB-style levels over `[0, max]` are a different quantity from the 20 PyRadiomics-style bins over + the ROI's range of `glszm3d.pyradiomics_bincount20`, which is why this fixture carries no oracle + claim. +- Every recipe here states `GLSZM_GREYDEPTH` explicitly rather than leaning on the value a settings + vector starts at. Zero is the no-binning setting, which `--coarseGrayDepth=0` or + `3glszm/greydepth=0` selects, and it does produce numbers, but it is a third configuration again: + at that setting every one of the sixteen pins above is off by between 1.6x and 1.5e6x. It has a + recipe of its own below. ## glszm3d.regression_ut_phantom_nobinning - The same segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `IBSI=false` and `GLSZM_GREYDEPTH=0` — no binning at all, the raw levels. **No oracle** — pinned Nyxus output in `test_3d_glszm_regression.h`, regenerated by `test_3d_glszm_dump_regression()`. -- **This is the configuration a run with no `--3glszm/greydepth` flag gets**, which is what earns it - a recipe rather than a footnote: `compile_feature_settings()` zero-fills the family's settings - vector and nothing writes `GLSZM_GREYDEPTH`, so 0 is the default reaching the feature. - `test_3d_glszm_default_greydepth_mechanics` asserts that separately; the sixteen pins here are the - numbers it produces, which finiteness alone was not saying. +- **This is the no-binning configuration**, which `--coarseGrayDepth=0` or `3glszm/greydepth=0` + selects. A run that names neither bins at the coarse grey depth, 64, where + `test_3d_glszm_default_greydepth_mechanics` asserts the features are finite; the sixteen pins here + are the numbers the raw levels produce, which finiteness alone was not saying. - **No oracle is available at this point on this fixture.** PyRadiomics discretises before it counts zones and has no "read the raw levels" mode over a 2001-level phantom; the same *setting* does have an oracle on a fixture small enough to carry one, which is `glszm3d.pyradiomics_ibsi_gapped`. @@ -1033,18 +1096,16 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `rel=1e-9` while all thirteen non-logarithm features of both tables passed there, which is the split `test_3d_glrlm_regression.h` and `test_3d_glszm_regression.h` already carry for `3GLRLM_RE` and `3GLSZM_ZE`, at the same `1e6`. -- The `GLDM_GREYDEPTH=0` cell is the compiled default rather than a variant of this one, so it is - pinned separately at `gldm3d.regression_ut_phantom_nobinning` below. +- The `GLDM_GREYDEPTH=0` cell is the no-binning configuration rather than a variant of this one, so it + is pinned separately at `gldm3d.regression_ut_phantom_nobinning` below. ## gldm3d.regression_ut_phantom_nobinning - The same phantom, label and `GREYDEPTH=64` as the recipe above, with `GLDM_GREYDEPTH=0` and `IBSI=false`. **No oracle** - Nyxus' own values, pinned in `test_3d_gldm_regression.h` and regenerated by `test_3d_gldm_dump_nobinning_regression()`. -- This is the **compiled default**, not a third configuration someone might choose: - `Environment::compile_feature_settings()` names no default for `GLDM_GREYDEPTH`, so the zero-filled - settings vector leaves it at 0, and only `--3gldm/greydepth=N` moves it. Every run that does not - pass that option computes the family here. `IBSI=true` reaches the same code path by forcing - `greyInfo = 0`. +- This is the **no-binning production point**: `--coarseGrayDepth=0` or `3gldm/greydepth=0` selects + it, and `IBSI=true` reaches the same code path by forcing `greyInfo = 0`. A run that names neither + bins at the coarse grey depth, 64, which is the recipe above. - It is a different quantity from the recipe above, not a rounding of it: on the same ROI `3GLDM_HGLE` is 4275550.79 against 1957.19 and `3GLDM_SDE` 0.86996 against 0.15361, so the `64` pins guard nothing here. `GREYDEPTH` is inert for this family and is held at 64 only so the two @@ -1055,16 +1116,14 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g ## gldm3d.regression_constant_roi - A synthetic 4x4x3 ROI, every voxel intensity 7, fed to `D3_GLDM_feature::calculate()` directly at - `GREYDEPTH=64`, `IBSI=false`, `GLDM_GREYDEPTH=0` - the compiled default - and a no-value sentinel of + `GREYDEPTH=64`, `IBSI=false`, `GLDM_GREYDEPTH=0` - no binning - and a no-value sentinel of `-98765.0`. Benchmark `bench_constant_roi_3d`. **No oracle claim** - the pin is Nyxus' current - output. The default is what this cell is asserted at because it is where the intercept below is the + output. No binning is what this cell is asserted at because it is where the intercept below is the only thing between the ROI and a matrix. - Reachable in production wherever a segmentation lands on a flat region. All fourteen come back as the sentinel (production default `0.0`, i.e. `--noval`) through `calculate()`'s `aux_min == - aux_max` intercept, whose comment says blank ROIs. At radiomics binning a second branch reaches the - same sentinel independently -- `to_grayscale_radiomix()`'s `binW = (max - min) / binCount` is zero, - so every voxel bins to background and `Nz == 0` -- which is the other reason this recipe is stated - at `GLDM_GREYDEPTH=0`. + aux_max` intercept, whose comment says blank ROIs. At radiomics binning `to_grayscale_radiomix()` + puts a range of zero width into one bin, so beneath the intercept every voxel is level 1 there too. - **PyRadiomics 3.0.1 computes a full GLDM on the same voxels** at `binWidth=1, gldm_a=0, distances=[1]`: `P_gldm` is 1x4, `[8, 20, 16, 4]` over one grey level. Bypassing the intercept as a negative control, Nyxus reproduces it on all seven dependence-axis features to the last bit diff --git a/tests/vetting/matrix/gldm3d.md b/tests/vetting/matrix/gldm3d.md index e6e7a072e..50555bab3 100644 --- a/tests/vetting/matrix/gldm3d.md +++ b/tests/vetting/matrix/gldm3d.md @@ -39,8 +39,8 @@ There is no GPU axis either: `D3_GLDM_feature::calculate()` has no `STNGS_USEGPU | `GLDM_GREYDEPTH` | `IBSI` | benchmark | verdict | recipe / oracle | |---|---|---|---|---| | `-20` (binCount 20) | false | `bench_compat_liver_3d` | **VALID(pyradiomics)** | `gldm3d.pyradiomics_bincount20`; all 14 features asserted in `test_3d_gldm_pyradiomics.h` at `abs=1e-9`, `3GLDM_DE` at `abs=4e-3` | -| `64` (MATLAB levels) | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim | -| `0` — **the compiled default** | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom_nobinning`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim — see below | +| `64` (MATLAB levels) — **the default**, the coarse grey depth | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim | +| `0` — no binning | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom_nobinning`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim — see below | | any | true | — | **same cell as the row above** | forced to `greyInfo = 0`, i.e. the same code path, reached a different way; the pins above are what guard it | | any | any | `bench_constant_roi_3d` | **DEFECT** → regression guard | nonempty constant-intensity ROI. The intercept below fires at every binning, so the cell spans the column; asserted at `0`, where it is the only cause — `gldm3d.regression_constant_roi`, see below | @@ -70,16 +70,14 @@ and so are the allocation, the row mapping and the fill loop on top of it. `gen_gldm3d_pyradiomics.py` rebuilds the whole matrix from the definition and requires all 163 cells to match PyRadiomics' C extension. -## The default cell +## The no-binning cell -`GLDM_GREYDEPTH = 0` is not one configuration among several — it is **the compiled default**. -`Environment::compile_feature_settings()` (`src/nyx/env_features.cpp`) zero-fills every settings -vector and then names a default for `GLCM_OFFSET`, `GLCM_GREYDEPTH`, `GLCM_NUMANG` and the `FPIMG_*` -group, and for nothing else; `GLDM_GREYDEPTH` is left at the zero-fill, and only -`--3gldm/greydepth=N` moves it. So every run that does not pass that option computes this family -here, and `IBSI=true` reaches the same path deliberately. Under SPEC §5.1 that makes it a real -default config no external tool is known to reproduce — **VALID-BUT-PRODUCTION-ONLY**, i.e. a -regression row, not an unmeasured cell. +`GLDM_GREYDEPTH = 0` is the family's no-binning production point: `--coarseGrayDepth=0` or +`3gldm/greydepth=0` selects it, and `IBSI=true` reaches the same path deliberately. A run that names +neither starts at the coarse grey depth, 64 — `Environment::compile_feature_settings()` gives +`GLDM_GREYDEPTH` that value — which is the row above it. Under SPEC §5.1 the raw-level point is a +real production config no external tool is known to reproduce — **VALID-BUT-PRODUCTION-ONLY**, +i.e. a regression row, not an unmeasured cell. The `64` snapshot cannot stand in for it. It is a genuinely different quantity, not a rounding — on `bench_ut57_3d` the same ROI gives: @@ -140,13 +138,11 @@ the raw intensity 7 as the grey level where PyRadiomics' `binWidth=1` maps it to under the intercept is wrong. **The intercept is the whole defect**, and what production emits today is the no-value sentinel — `--noval`, default `0.0` — for all fourteen. -**A fix is still not one line, because the other binning schemes fail differently.** At radiomics -binning `TextureFeature::to_grayscale_radiomix()` computes `binW = (max - min) / binCount`, which is -zero here: every voxel bins to `0`, no dependence zone is gathered, and the `Nz == 0` branch returns -the same sentinel by a second route. That path also divides by zero and converts the resulting NaN to -`PixIntens`, which the intercept is currently what keeps unreachable — so narrowing the intercept -without touching the binning would trade a wrong answer for undefined behaviour. That is why this -cell is asserted at `GLDM_GREYDEPTH=0`, where the intercept stands alone. +**Under every binning scheme the intercept is what answers.** At radiomics binning +`TextureFeature::to_grayscale_radiomix()` puts a range of zero width into one bin, so beneath the +intercept every voxel would be level 1 — the same one-level matrix as at no binning, on a level of +its own number. The cell is asserted at `GLDM_GREYDEPTH=0` because that is where the bypass was +measured against PyRadiomics. It is guarded rather than fixed here: `test_3d_gldm_constant_roi_regression()` pins the emitted value for all fourteen, under a `--noval` sentinel no GLDM feature can take, so a zero-filled buffer cannot diff --git a/tests/vetting/matrix/gldzm.md b/tests/vetting/matrix/gldzm.md index 8f8754afa..a57a91b68 100644 --- a/tests/vetting/matrix/gldzm.md +++ b/tests/vetting/matrix/gldzm.md @@ -24,7 +24,7 @@ angle or alpha axis at all, unlike GLCM, GLRLM or NGLDM. | True | none (identity on an already-discrete fixture) | phantom's own 1..6 | VALID | `gldzm.ibsi_phantom_2d` — mirp + ibsi | | True | none | phantom's own 1..6 | VALID-prod-only, 2 features | `GLDZM_GLM`, `GLDZM_ZDM` — no oracle exposes either → `test_2d_gldzm_regression.h` | | False | MATLAB (`GREYDEPTH > 0`) | any | NOT MEASURED | see below | -| False | radiomics (`GREYDEPTH < 0`) | any | NOT MEASURED | see below | +| False | radiomics (`GREYDEPTH < 0`) | 20 bins | VALID, 6 features | `gldzm.mirp_fbn20_negdepth` — mirp on `bench_square12_graded`, the six features that read no border distance; the other ten NOT MEASURED, see below | | any | any | ROI with `aux_min == aux_max` | INVALID | degenerate — a blank ROI has no zones; `calculate()` returns NaN before building a matrix, guarded in code rather than by an oracle | ## Why the IBSI point is one row and not one per level count @@ -80,8 +80,15 @@ value is a bug in the test, and per SPEC §6.3.1 a table named `_ibsi` may not h The production path (`IBSI=false`) is reachable for 2D GLDZM and is a genuinely different level assignment, in two variants: MATLAB binning at `coarse_gray_depth` and radiomics binning at -`GREYDEPTH < 0`. **No 2D GLDZM assertion in the tree runs on either** — every test in -`test_2d_gldzm_{ibsi,mirp,regression}.h` calls `make_gldzm2d_settings(true)` — and this family's -vetting did not measure them. They are recorded here as open points rather than omitted, so the next -revisit knows they were never triaged rather than assuming they were ruled out. Note this is a -weaker position than GLDM's, which at least drift-pins its MATLAB-binned production point. +`GREYDEPTH < 0`. + +**MATLAB binning** has no assertion in the tree and was not measured. It is recorded here as an open +point rather than omitted, so the next revisit knows it was never triaged. Note this is a weaker +position than GLDM's, which at least drift-pins its MATLAB-binned production point. + +**Radiomics binning** is vetted on six features, `gldzm.mirp_fbn20_negdepth`. The other ten read a +zone's border distance, and the fixture cannot judge them: `bench_square12_graded` fills its bounding +box, so a zone's distance to the ROI border is its distance to the frame under any definition. On a +ROI with background inside it the 2D distance map and IBSI's part -- measured on a disk over a +gradient at no binning, `GLDZM_SDE` 0.0607 against MIRP's 0.0993 -- so the ten wait on that, not on +the binning. diff --git a/tests/vetting/matrix/gldzm3d.md b/tests/vetting/matrix/gldzm3d.md index 3f1d2b6a2..6d3eeea86 100644 --- a/tests/vetting/matrix/gldzm3d.md +++ b/tests/vetting/matrix/gldzm3d.md @@ -38,15 +38,15 @@ at every cell even though no tool computes them. |---|---|---|---|---|---| | 1 | **none** — grey level = the voxel's own value | `IBSI=true` (any `GREYDEPTH`), or `GREYDEPTH=0, IBSI=false` | **VALID(mirp)** | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom` | the 16 pinned in `test_3d_gldzm_mirp.h` at an absolute 1e-9, measured residual 5.7e-15; `GLM`/`ZDM` pinned in `test_3d_gldzm_regression.h`. `test_3d_gldzm_no_binning_spellings_agree_mechanics` holds the two spellings to one set of values; `test_3d_gldzm_zero_level_voxels_are_zoned_mechanics` holds the level-0 lift this point needs | | 2 | **MATLAB** — `floor(n·i / ROI max) + 1`, clipped into `[1, n]` | `GREYDEPTH > 0, IBSI=false` | **VALID-BUT-PRODUCTION-ONLY** | 18 `regression` at `gldzm3d.regression_ut_phantom` | all 18 pinned in `test_3d_gldzm_regression.h` at `rel=1e-9` on `bench_ut57_3d`. No tool reproduces this scheme — see "Why point 2 has no oracle" | -| 3 | **radiomics** — `(i − ROI min) / binW + 1`, `binW = (max − min) / n` | `GREYDEPTH < 0, IBSI=false` | **VALID(mirp)** at a bin count the scheme maps identically | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom_radiomics` | the 16 asserted against MIRP **at this cell's own settings** in `test_3d_gldzm_mirp.h`, `GREYDEPTH=-8` on `bench_compat_gldzm_3d`; `GLM`/`ZDM` pinned beside them. `test_3d_gldzm_radiomics_binning_is_identity_here_mechanics` holds the identity that is the *reason* MIRP's goldens transfer — the coverage is the 16 rows, not the equivalence; `test_3d_gldzm_zero_level_voxels_are_zoned_radiomics_mechanics` holds the level-0 lift this point needs, which gathers its levels as a set rather than a ladder and so is its own code path | +| 3 | **radiomics** — IBSI's fixed bin number, `floor(n (i − ROI min) / (max − min)) + 1` | `GREYDEPTH < 0, IBSI=false` | **VALID(mirp)**, at a bin count the scheme maps identically and at one that re-bins | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom_radiomics`; 16 `vetted` at `gldzm3d.mirp_fbn20_negdepth` | the 16 asserted against MIRP **at this cell's own settings** in `test_3d_gldzm_mirp.h`, `GREYDEPTH=-8` on `bench_compat_gldzm_3d`; `GLM`/`ZDM` pinned beside them. `test_3d_gldzm_negative_greydepth_mirp` asserts the 16 again at `GREYDEPTH=-20` on `bench_ut57_3d`, where 2001 levels fold into 20 and MIRP's `fixed_bin_number` bins for itself, worst residual 2.4e-16. `test_3d_gldzm_radiomics_binning_is_identity_here_mechanics` holds the identity that is the *reason* MIRP's goldens transfer — the coverage is the 16 rows, not the equivalence; `test_3d_gldzm_zero_level_voxels_are_zoned_radiomics_mechanics` holds the level-0 lift this point needs, which gathers its levels as a set rather than a ladder and so is its own code path | **What point 3 does and does not establish.** At `GREYDEPTH=-8` the scheme is the identity on this fixture's levels 1..8: `to_grayscale_radiomix` maps them over a bin width of 7/8 back onto -themselves, the top level clipping into the last bin. So the cell is vetted **at that bin count on -that fixture**. A bin count that actually re-bins is a different matter — there the scheme is a -Nyxus convention with the same lower-bin-edge question point 2 has, it bins from the ROI minimum -rather than 0, which is closer to what the tools do, and the fixture to measure it on does not exist -yet. That configuration is the one thing about this family still unexercised. +themselves, the top level clipping into the last bin. So that recipe vets the cell **at that bin +count on that fixture**. A bin count that actually re-bins is `gldzm3d.mirp_fbn20_negdepth`: the +scheme bins from the ROI minimum, as the tools do, so MIRP's `fixed_bin_number` is config-matched to +it with no level reproduction on the MIRP side, and the 16 features agree at 20 bins on the segmented +phantom. ## Reference mappings, and the evidence behind the verdicts @@ -76,10 +76,9 @@ would then sit beside point 1's rather than replacing them. ## What is not covered -**One thing: the radiomics scheme at a bin count that actually re-bins.** Point 3 is vetted at a bin -count the scheme maps identically, which is what makes MIRP's goldens applicable to it; a bin count -that changes the levels puts the cell back into the same lower-bin-edge question point 2 has, and -covering it needs a fixture that does not exist yet, not new plumbing. +**Nothing at the three points.** Point 3 is vetted both at a bin count it maps identically and at one +that re-bins, so the radiomics scheme is covered where it changes the levels as well as where it does +not. Point 2 has no oracle, for the reason given above, and is drift-pinned. `3GLDZM_GLM` and `3GLDZM_ZDM` are **not** in this list. They cannot be *vetted* anywhere — MIRP's GLDZM emits no `dzm_gl_mean` / `dzm_zd_mean` column and IBSI defines neither — but they are Nyxus diff --git a/tests/vetting/matrix/glszm3d.md b/tests/vetting/matrix/glszm3d.md index 4befdf742..8f03b8380 100644 --- a/tests/vetting/matrix/glszm3d.md +++ b/tests/vetting/matrix/glszm3d.md @@ -77,21 +77,25 @@ gapped assertion and the connectivity one. ## `GLSZM_GREYDEPTH == 0` is a third configuration, not a variant of the other two -At MATLAB binning the background level is bin 1 (`zeroI = 1`), so a voxel binned there starts no zone -of its own; at radiomics binning and at no binning the background is intensity 0. That is a -different quantity, not a different resolution of the same one, which is why the recipes state the -value explicitly instead of leaning on the zero a settings vector starts at. +The three schemes bin different quantities, not one quantity at different resolutions: MATLAB binning +scales `[0, max]` onto levels `1..n`, radiomics binning scales the ROI's own `[min, max]`, and no +binning keeps the raw levels. That is why the recipes state the value explicitly instead of leaning +on the zero a settings vector starts at. Under all three the background outside the ROI is level 0, +set from the ROI's voxel cloud rather than read off the binned value (MATLAB binning sends intensity 0 +to level 1, which the ROI's darkest voxels carry too); +`test_3d_texture_background_level1_voxels_kept_mechanics` and +`test_3d_texture_background_by_roi_mask_mechanics` assert it in RAM and out of core. The unwired version of `test_3d_glszm_regression.h` did lean on it: it set `GREYDEPTH=64` and left `GLSZM_GREYDEPTH` at 0, and at that setting every one of its sixteen pins is wrong by between 1.6× and 1.5e6× (`tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md`, §"What the orphan would have done"). -**It is the default a real run gets, so it carries numbers and not only a finiteness check.** +**The default a real run gets is the coarse grey depth, 64 MATLAB levels.** `test_3d_glszm_default_greydepth_mechanics` asserts that `compile_feature_settings()` really does -deliver `GLSZM_GREYDEPTH = 0` and that the sixteen features are finite there — that is mechanics, and -mechanics is all it is. The values themselves are pinned by `glszm3d.regression_ut_phantom_nobinning`, -sixteen `%.17g` goldens on `bench_ut57_3d` under `TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION`. They +deliver `GLSZM_GREYDEPTH = 64` and that the sixteen features are finite there — that is mechanics, and +mechanics is all it is. The no-binning values are pinned by `glszm3d.regression_ut_phantom_nobinning`, +sixteen `%.17g` goldens on `bench_ut57_3d` under `TEST_3D_GLSZM_NO_BINNING_REGRESSION`. They claim no oracle: PyRadiomics discretises before it counts zones and has no counterpart for reading 2001 raw levels off this phantom. The *setting* is vetted, on the fixture small enough to carry an oracle — `glszm3d.pyradiomics_ibsi_gapped`, the row above. @@ -108,9 +112,9 @@ Nyxus returns the soft-NaN sentinel for all sixteen instead, which is `--noval` **Dispositioned `VALID-prod-only`, not `INVALID`.** It is a configuration a real run reaches and no external tool reproduces, which is what SPEC §5.1 gives that disposition to, so it earns a regression row rather than a dropped one — and the cell says in full that the behaviour it pins is a defect. -Calling it neither vetted nor invalid is the whole point. The guard is doing real work at radiomics -binning, where `to_grayscale_radiomix` divides by `(max - min)` and would divide by zero; it is -unconditional, so it also discards the two schemes that would have answered. Whether to narrow it is +Calling it neither vetted nor invalid is the whole point. The guard is unconditional, so it +discards every scheme's answer: at radiomics binning `to_grayscale_radiomix` puts a range of zero width +into one bin, so there too a matrix of one level is what lies beneath it. Whether to narrow it is `src/` work on its own branch — it changes a public feature's output on a reachable input — so this pass pins the current behaviour rather than changing it: `test_3d_glszm_constant_roi_regression` runs a constant 2×2×2 volume with the sentinel set to a distinctive `-98765` and asserts all sixteen come diff --git a/tests/vetting/matrix/ngldm3d.md b/tests/vetting/matrix/ngldm3d.md index 4c440f084..6b8b4697d 100644 --- a/tests/vetting/matrix/ngldm3d.md +++ b/tests/vetting/matrix/ngldm3d.md @@ -8,9 +8,11 @@ settings struct at large: prepare_NGLDM_matrix_kit (NGLDM, greyLevelsLUT, Ng, Nr, r, STNGS_NGREYS(s), STNGS_IBSI(s)); ``` -Two, therefore: **grey binning** (`GREYDEPTH`, reaching the feature as `n_greys`) and **IBSI mode** -(`IBSI`, which `to_grayscale` reads as `disable_binning` — so it does not select a different ladder, -it turns binning off and makes the raw intensity the grey level). +Two, therefore: **grey binning** (`GREYDEPTH`, reaching the feature as `n_greys`, whose sign selects +the scheme as in every texture family -- positive is that many levels over `[0, ROI max]`, 0 is the raw +levels, negative is `abs()` PyRadiomics-style bins over the ROI's own range) and **IBSI mode** (`IBSI`, +which keeps the raw intensity as the grey level -- so it does not select a different ladder, it turns +binning off). Two things that would be axes in the IBSI definition are **not settable** here, and that is part of the dispositions below: @@ -29,8 +31,10 @@ One row per Nyxus config point, verdict per SPEC §5.1. | GREYDEPTH | IBSI | verdict | oracle / reason | |---|---|---|---| | 64 | false | **VALID** | `mirp` at recipe `ngldm3d.mirp_samelevels` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-3`. The same point carries the family's three remaining drift guards, `3NGLDM_DCP` / `3NGLDM_GLM` / `3NGLDM_DCM`, on `bench_ut57_3d` at `rel=1e-9` (`ngldm3d.regression_ut_phantom`) — the only three no tool can judge | -| any other | false | **VALID** — same cell | `GREYDEPTH` sets the ladder's height, not its kind. Every depth reaches MIRP the way `ngldm3d.mirp_samelevels` does, so it is one cell exercised at the depth the tests pin (64), not a family of cells | -| any | true | **VALID** | `mirp` at recipe `ngldm3d.mirp_ibsi_rawlevels` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-3`, worst measured residual 7.54e-15. `IBSI` reaches `to_grayscale` as `disable_binning`, so this point does not bin: the raw intensity is the grey level (2001 distinct here) and MIRP at `base_discretisation_method="none"` matches by construction. `GREYDEPTH` is not read when `IBSI=true`, which is why the cell spans every depth | +| any other > 0 | false | **VALID** — same cell | a positive `GREYDEPTH` sets the ladder's height, not its kind. Every positive depth reaches MIRP the way `ngldm3d.mirp_samelevels` does, so it is one cell exercised at the depth the tests pin (64), not a family of cells | +| 0 | false | **VALID** — the `IBSI=true` cell | no binning: the raw intensity is the grey level, exactly as at `IBSI=true`. `test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics` holds all nineteen features equal to that run bit for bit, so the cell below covers it | +| < 0 | false | **VALID** | `mirp` at recipe `ngldm3d.mirp_fbn20_negdepth` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-9` (`3NGLDM_DCENT` at `rel=1e-6`), `GREYDEPTH=-20`, worst measured residual 5.1e-16. IBSI's fixed bin number over the ROI's range, which MIRP's `fixed_bin_number` computes for itself, so the binning is compared too | +| any | true | **VALID** | `mirp` at recipe `ngldm3d.mirp_ibsi_rawlevels` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-3`, worst measured residual 7.54e-15. `IBSI` keeps the raw level, so this point does not bin: the raw intensity is the grey level (2001 distinct here) and MIRP at `base_discretisation_method="none"` matches by construction. `GREYDEPTH` is not read when `IBSI=true`, which is why the cell spans every depth | `d` and `alpha` add no rows: neither can be varied from settings, so there is no further cross-product and no `INVALID` cell to record. @@ -59,10 +63,14 @@ feature formulas over it. It does **not** cover the discretisation: the levels a comparison rather than a result of it, since the generator reproduces Nyxus' binning in numpy. `ngldm3d.mirp_ibsi_rawlevels` (the `IBSI=true` cell) is **not** narrowed, because there is no binning -step to reproduce — `disable_binning` makes the raw intensity the grey level on both sides. It is the +step to reproduce — the raw intensity is the grey level on both sides. It is the weaker discriminator of the two (83.46% of ROI voxels have no matching neighbour, maximum dependence -17 of 26) and the wider in scope. Between them the family's whole config axis is asserted, and -Nyxus' `GREYDEPTH` binning itself remains judged nowhere. +17 of 26) and the wider in scope. + +`ngldm3d.mirp_fbn20_negdepth` (the negative-`GREYDEPTH` cell) is not narrowed either: MIRP bins the +ROI itself at `fixed_bin_number` n=20 and Nyxus at `GREYDEPTH=-20`, and the two agree to 5.1e-16, so +there the binning is judged as well. The positive scheme is the one binning still judged nowhere -- +its lower bin edge of 0 has no tool counterpart, as the mappings above record. ## The three features with no oracle row diff --git a/tests/vetting/oracle_coverage.csv b/tests/vetting/oracle_coverage.csv index 174c2bffc..c56c49bf3 100644 --- a/tests/vetting/oracle_coverage.csv +++ b/tests/vetting/oracle_coverage.csv @@ -298,18 +298,24 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 2D,GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_SDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_SDE_MIRP,ibsi_digital_phantom 2D,GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_LDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDE_MIRP,ibsi_digital_phantom 2D,GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_LGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LGLZE_MIRP,ibsi_digital_phantom +2D,GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_HGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_HGLZE_MIRP,ibsi_digital_phantom +2D,GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_SDLGLE_MIRP,ibsi_digital_phantom 2D,GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_SDHGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_SDHGLE_MIRP,ibsi_digital_phantom 2D,GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_LDLGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDLGLE_MIRP,ibsi_digital_phantom 2D,GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_LDHGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDHGLE_MIRP,ibsi_digital_phantom 2D,GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_GLNU_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNU_MIRP,ibsi_digital_phantom +2D,GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_GLNUN_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNUN_MIRP,ibsi_digital_phantom +2D,GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_ZDNU_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDNU_MIRP,ibsi_digital_phantom 2D,GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_ZDNUN_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDNUN_MIRP,ibsi_digital_phantom 2D,GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_ZP_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZP_MIRP,ibsi_digital_phantom +2D,GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_GLM,gldzm,regression,,,gldzm.ibsi_phantom_2d,rel=1e-3,test_2d_gldzm_regression.h,,,,audit,"not an IBSI GLDZM feature and mirp exposes no column for it, so nothing independent covers it; drift-pinned on the IBSI phantom in test_2d_gldzm_regression.h at rel=1e-3. Value re-recorded after the zone-connectivity fix (8-connected zones), see audit/gldzm_2d_mirp_vetting_report.md",TEST_NYXUS.TEST_2D_GLDZM_GLM_REGRESSION,ibsi_digital_phantom 2D,GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_GLV_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLV_MIRP,ibsi_digital_phantom +2D,GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm.mirp_fbn20_negdepth,rel=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,GLDZM_ZDM,gldzm,regression,,,gldzm.ibsi_phantom_2d,rel=1e-3,test_2d_gldzm_regression.h,,,,audit,"not an IBSI GLDZM feature and mirp exposes no column for it, so nothing independent covers it; drift-pinned on the IBSI phantom in test_2d_gldzm_regression.h at rel=1e-3. Value re-recorded after the zone-connectivity fix (8-connected zones), see audit/gldzm_2d_mirp_vetting_report.md",TEST_NYXUS.TEST_2D_GLDZM_ZDM_REGRESSION,ibsi_digital_phantom 2D,GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_ZDV_MIRP,ibsi_digital_phantom 2D,GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm.ibsi_phantom_2d,abs=1e-9,test_2d_gldzm_ibsi.h;test_2d_gldzm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py",TEST_NYXUS.TEST_2D_GLDZM_ZDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDE_MIRP,ibsi_digital_phantom @@ -344,24 +350,40 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 2D,GLDM_LDLGLE,gldm,vetted,pyradiomics,agreed,gldm.ibsi_phantom_2d,rel=1e-9,test_2d_gldm_ibsi.h;test_2d_gldm_pyradiomics.h,,,,audit,"vetted vs pyradiomics v3.0.1 GLDM on the four IBSI phantom slices (binWidth=1 identity binning, gldm_a=0, distances=[1], force2D), recipe gldm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: pyradiomics computes each slice on its own, so both quantities are pinned in test_2d_gldm_pyradiomics.h at rel=1e-9 (worst residual 1.0e-15 over the 14 features x 4 slices). The mean alone is blind to errors in two slices that cancel. The same means are pinned against the published IBSI consensus in test_2d_gldm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to; IBSI publishes them under the NGLDM name because a GLDM dependence count is IBSI's j = k + 1 at alpha=0, d=1. The production config (ibsi=false, MATLAB binning) is not comparable to pyradiomics and is drift-pinned only in test_2d_gldm_regression.h. gen_gldm_pyradiomics.py",TEST_NYXUS.TEST_2D_GLDM_LDLGLE_PYRADIOMICS,ibsi_digital_phantom 2D,GLDM_LDHGLE,gldm,vetted,pyradiomics,agreed,gldm.ibsi_phantom_2d,rel=1e-9,test_2d_gldm_ibsi.h;test_2d_gldm_pyradiomics.h,,,,audit,"vetted vs pyradiomics v3.0.1 GLDM on the four IBSI phantom slices (binWidth=1 identity binning, gldm_a=0, distances=[1], force2D), recipe gldm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: pyradiomics computes each slice on its own, so both quantities are pinned in test_2d_gldm_pyradiomics.h at rel=1e-9 (worst residual 1.0e-15 over the 14 features x 4 slices). The mean alone is blind to errors in two slices that cancel. The same means are pinned against the published IBSI consensus in test_2d_gldm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to; IBSI publishes them under the NGLDM name because a GLDM dependence count is IBSI's j = k + 1 at alpha=0, d=1. The production config (ibsi=false, MATLAB binning) is not comparable to pyradiomics and is drift-pinned only in test_2d_gldm_regression.h. gen_gldm_pyradiomics.py",TEST_NYXUS.TEST_2D_GLDM_LDHGLE_PYRADIOMICS,ibsi_digital_phantom 2D,NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCP,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, 2D,NGLDM_GLM,ngldm,regression,,disagrees,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_regression.h,,,,audit,"regression: a Nyxus mean-style row with no IBSI NGLDM counterpart and no mirp column (mirp exposes no grey-level-mean or dependence-count-mean), so no oracle can reproduce it. Drift-pinned at rel=1e-9 in test_2d_ngldm_regression.h. The previous row claimed oracle=mirp and targeted a test_2d_ngldm_mirp.h that did not exist.",, 2D,NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCM,ngldm,regression,,disagrees,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_regression.h,,,,audit,"regression: a Nyxus mean-style row with no IBSI NGLDM counterpart and no mirp column (mirp exposes no grey-level-mean or dependence-count-mean), so no oracle can reproduce it. Drift-pinned at rel=1e-9 in test_2d_ngldm_regression.h. The previous row claimed oracle=mirp and targeted a test_2d_ngldm_mirp.h that did not exist.",, 2D,NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-6,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm.ibsi_phantom_2d,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py",, +2D,NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm.mirp_fbn20_negdepth,rel=1e-9,test_2d_ngldm_ibsi.h;test_2d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_square12_graded 2D,NGTDM_COARSENESS,ngtdm,vetted,mirp,agreed,ngtdm.ibsi_phantom_2d,abs=1e-9,test_2d_ngtdm_ibsi.h;test_2d_ngtdm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md",TEST_NYXUS.TEST_2D_NGTDM_COARSENESS_IBSI;TEST_NYXUS.TEST_2D_NGTDM_COARSENESS_MIRP,ibsi_digital_phantom 2D,NGTDM_CONTRAST,ngtdm,vetted,mirp,agreed,ngtdm.ibsi_phantom_2d,abs=1e-9,test_2d_ngtdm_ibsi.h;test_2d_ngtdm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md",TEST_NYXUS.TEST_2D_NGTDM_CONTRAST_IBSI;TEST_NYXUS.TEST_2D_NGTDM_CONTRAST_MIRP,ibsi_digital_phantom 2D,NGTDM_BUSYNESS,ngtdm,vetted,mirp,agreed,ngtdm.ibsi_phantom_2d,abs=1e-9,test_2d_ngtdm_ibsi.h;test_2d_ngtdm_mirp.h,,,,audit,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md",TEST_NYXUS.TEST_2D_NGTDM_BUSYNESS_IBSI;TEST_NYXUS.TEST_2D_NGTDM_BUSYNESS_MIRP,ibsi_digital_phantom @@ -739,114 +761,130 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3GLCM_SUMVARIANCE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, 3D,3GLDM_DE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=4e-3,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. 3GLDM_DE is the exception at abs=4e-3: it is the family's only sum over logarithms and Nyxus takes it through fast_log10(), a float-precision approximation divided by a ten-digit LOG10_2, where PyRadiomics uses numpy.log2. Measured residual 1.7512e-3 absolute / 2.65e-4 relative (Nyxus 6.6031219389041276 against PyRadiomics 6.6048731874541904); the band is that doubled and rounded up to one significant figure. A documented fast path, banded rather than reported. Note the 2D twin's identical calc_DE() measures 1.3e-3 RELATIVE, five times wider, so this figure is this family's own and not carried across. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-6,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band.",TEST_NYXUS.TEST_3D_GLDM_DE_REGRESSION,bench_ut57_3d -3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band.",TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band.",TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_DN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DN_REGRESSION,bench_ut57_3d -3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_DNN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DNN_REGRESSION,bench_ut57_3d -3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_DV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DV_REGRESSION,bench_ut57_3d -3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_GLN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_GLN_REGRESSION,bench_ut57_3d -3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_GLV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_GLV_REGRESSION,bench_ut57_3d -3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_HGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_HGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_LDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDE_REGRESSION,bench_ut57_3d -3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_LDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_LDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_LGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. Specific to this feature: the retired table pinned 3GLDM_LGLE at 0.26, byte-identical to the 3GLDM_SDE pin beside it, against a measured 0.00073572128237550161 - a factor of 353 - and test_3d_gldm_lgle_regression() asserted Feature3D::GLDM_SDE under the _lgle_ name, so the feature had no drift guard at all and 3GLDM_SDE had two. Both halves of one paste, in a file nothing ran.",TEST_NYXUS.TEST_3D_GLDM_LGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_SDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDE_REGRESSION,bench_ut57_3d -3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_SDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDM_SDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_REGRESSION,bench_ut57_3d -3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,bench_ut57_3d +3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,bench_ut57_3d 3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d 3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,bench_ut57_3d +3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,bench_ut57_3d +3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LGLZE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,bench_ut57_3d +3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_HGLZE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,bench_ut57_3d +3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDLGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,bench_ut57_3d +3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDHGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,bench_ut57_3d +3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDLGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,bench_ut57_3d +3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDHGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,bench_ut57_3d +3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNU,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,bench_ut57_3d +3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNUN,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,bench_ut57_3d +3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNU,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,bench_ut57_3d +3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNUN,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,bench_ut57_3d +3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZP,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,bench_ut57_3d +3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_REGRESSION,bench_ut57_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.mirp_compat_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_COMPAT_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_RADIOMICS_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLV,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,bench_ut57_3d +3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.mirp_compat_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_COMPAT_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_RADIOMICS_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDV,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,bench_ut57_3d +3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,bench_ut57_3d +3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-6,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCP,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,non-discriminating-agreement,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would pin the same Nyxus run to a second literal and add no path or config coverage. This one carries no oracle row because Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, at both config points -- an agreement that cannot fail for the reasons an assertion should fail. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCP_REGRESSION,bench_ut57_3d 3D,3NGLDM_GLM,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLM_REGRESSION,bench_ut57_3d 3D,3NGLDM_DCM,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCM_REGRESSION,bench_ut57_3d @@ -867,21 +905,37 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_samelevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,scoped-oracle,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENT_MIRP,bench_ut57_3d 3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_samelevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,scoped-oracle,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,bench_ut57_3d 3D,3NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-6,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,bench_ut57_3d +3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d 3D,3NGTDM_COARSENESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_COARSENESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_R2_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_COARSENESS,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,bench_ut57_3d @@ -900,67 +954,67 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3GLSZM_SAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SZN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SZN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,bench_ut57_3d -3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SZNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SZNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,bench_ut57_3d -3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZP,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZP,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-3,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=2e-3,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_ZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_HGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_HGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,bench_ut57_3d +3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant 3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant 3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant diff --git a/tests/vetting/oracles/gen_gldzm3d_mirp.py b/tests/vetting/oracles/gen_gldzm3d_mirp.py index a17df5dca..d20c33b44 100644 --- a/tests/vetting/oracles/gen_gldzm3d_mirp.py +++ b/tests/vetting/oracles/gen_gldzm3d_mirp.py @@ -1,8 +1,10 @@ """OFFLINE MIRP oracle for the 3D GLDZM features. - python tests/vetting/oracles/gen_gldzm3d_mirp.py (from the repository root) + python tests/vetting/oracles/gen_gldzm3d_mirp.py (from the repository root) + python tests/vetting/oracles/gen_gldzm3d_mirp.py --check (verify only, no tables) + python tests/vetting/oracles/gen_gldzm3d_mirp.py --write-phantom (rewrite both fixtures) -Runs MIRP three times and re-verifies everything the tree quotes from it, exiting non-zero on any +Runs MIRP four times and re-verifies everything the tree quotes from it, exiting non-zero on any mismatch, on any quoted feature it cannot produce, and on any feature it produces that nothing quotes. @@ -22,6 +24,19 @@ 3. `gldzm3d.mirp_samelevels` -- the same fixture with MIRP handed the grey levels Nyxus bins to, so the GLDZM itself is what is compared there too. + 4. `gldzm3d.mirp_fbn20_negdepth` -- the negative coarse grey depth on the segmented phantom. + GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], which is + IBSI's fixed bin number, floor(20 (x - min) / (max - min)) + 1, and exactly what MIRP's + `base_discretisation_method="fixed_bin_number"`, n_bins=20, computes. So MIRP discretises here + itself, nothing of Nyxus' binning is reproduced on the MIRP side, and the table covers the + binning as well as the GLDZM. MIRP is handed the integer levels Nyxus loads the float phantom + as (the volume shifted by its minimum), which is the loader's step and not the binning. Over the + ROI those span 1024-3024, so the bin width is exactly 100: 2736 ROI voxels sit on an interior + bin edge, and a division by that width bins every one of them as IBSI does. The 2D square of + gen_gldzm_mirp.py is the fixture that separates the two formulas. Verified against + gldzm_3d_mirp_negdepth_ref_vals in tests/test_3d_gldzm_mirp.h, held at rel 1e-12 -- the pins are + printed at full precision, so this is a staleness check, not a vetting band. + Runs 2 and 3 pin nothing. The artifact they feed is ../audit/gldzm_3d_mirp_vetting_report.md, and that is what this generator checks them against. @@ -76,6 +91,8 @@ LABEL = 57 NBINS = 64 +NEGDEPTH_NBINS = 20 +NEGDEPTH_TABLE = "gldzm_3d_mirp_negdepth_ref_vals" # The header pins MIRP's values in full, so they are held to the exact tier the assertions use. PIN_RELTOL = 1e-12 @@ -108,6 +125,7 @@ SUFFIX_NONE = "_3d" # MIRP drops the discretisation stem when there is none SUFFIX_FBN = "_3d_fbn_n%d" % NBINS +SUFFIX_NEGDEPTH = "_3d_fbn_n%d" % NEGDEPTH_NBINS NIFTI_DTYPE = {2: np.uint8, 4: np.int16, 8: np.int32, 16: np.float32, 64: np.float64, 768: np.uint32} @@ -420,6 +438,7 @@ def verify(got, quoted, what, tol): def main(): write = "--write-phantom" in sys.argv[1:] + check = "--check" in sys.argv[1:] for p in (INTEN, MASK): if not os.path.exists(p): print("missing phantom: " + p) @@ -470,6 +489,12 @@ def features(image, mask, spacing, suffix, **discretisation): base_discretisation_n_bins=NBINS) same = features(levels, m32, spacing, SUFFIX_NONE, base_discretisation_method="none") + # The negative grey depth: MIRP bins the loader-shifted levels itself, at 20 bins. + raw_levels = (inten.astype(np.int64) - int(inten.min())).astype(np.float64) + neg = features(raw_levels, m32, spacing, SUFFIX_NEGDEPTH, + base_discretisation_method="fixed_bin_number", + base_discretisation_n_bins=NEGDEPTH_NBINS) + try: version = metadata.version("mirp") # mirp exposes no __version__ except metadata.PackageNotFoundError: @@ -478,14 +503,23 @@ def features(image, mask, spacing, suffix, **discretisation): # the installed mirp, read from the distribution rather than written in: this line is the # provenance of the values printed below it, so a run under another version has to say so. print("# mirp %s, numpy %s, label=%d, by_slice=False" % (version, np.__version__, LABEL)) - for title, got, suffix in (("gldzm3d.mirp_compat_phantom", compat, SUFFIX_NONE), - ("gldzm3d.mirp_fbn64", fbn, SUFFIX_FBN), - ("gldzm3d.mirp_samelevels", same, SUFFIX_NONE)): - print("\n# " + title) - for name in sorted(got): - print(('\t{"%s", %r},' % (name, got[name])).ljust(56) - + "// " + MIRP[name] + suffix) - print("\n# no MIRP counterpart at any recipe: 3GLDZM_GLM, 3GLDZM_ZDM") + if not check: + for title, got, suffix in (("gldzm3d.mirp_compat_phantom", compat, SUFFIX_NONE), + ("gldzm3d.mirp_fbn64", fbn, SUFFIX_FBN), + ("gldzm3d.mirp_samelevels", same, SUFFIX_NONE)): + print("\n# " + title) + for name in sorted(got): + print(('\t{"%s", %r},' % (name, got[name])).ljust(56) + + "// " + MIRP[name] + suffix) + print("\n# gldzm3d.mirp_fbn20_negdepth, paste-ready") + print("static const ref_vals_map %s{" % NEGDEPTH_TABLE) + names = list(MIRP) + for i, name in enumerate(names): + sep = "," if i < len(names) - 1 else "" + print('\t\t{ "%s",\t%r }%s\t\t// %s%s' % (name, neg[name], sep, MIRP[name], + SUFFIX_NEGDEPTH)) + print("};") + print("\n# no MIRP counterpart at any recipe: 3GLDZM_GLM, 3GLDZM_ZDM") nok = nmiss = 0 nfail = bad_phantom @@ -500,6 +534,14 @@ def features(image, mask, spacing, suffix, **discretisation): nmiss += c unquoted += d + # the negdepth table pins all sixteen, so the reverse direction (a feature MIRP computes that the + # table does not pin) fails the run as well + a, b, c, d = verify(neg, parse_pins(HEADER, NEGDEPTH_TABLE), NEGDEPTH_TABLE, PIN_RELTOL) + nok += a + nfail += b + nmiss += c + unquoted += d + if not os.path.exists(REPORT): print("\n# %s is missing -- there is nothing the published tables can be checked against, " "which is a failure, not a pass" % os.path.basename(REPORT)) diff --git a/tests/vetting/oracles/gen_gldzm_mirp.py b/tests/vetting/oracles/gen_gldzm_mirp.py index c9cb8e11d..3821ec4a8 100644 --- a/tests/vetting/oracles/gen_gldzm_mirp.py +++ b/tests/vetting/oracles/gen_gldzm_mirp.py @@ -1,10 +1,11 @@ -"""OFFLINE mirp oracle for the 2D GLDZM features, on the IBSI digital phantom. +"""OFFLINE mirp oracle for the 2D GLDZM features, on the IBSI digital phantom and bench_square12_graded. - python tests/vetting/oracles/gen_gldzm_mirp.py (from the repository root) + python tests/vetting/oracles/gen_gldzm_mirp.py (from the repository root) + python tests/vetting/oracles/gen_gldzm_mirp.py --check (verify only, no paste-ready tables) -Prints the paste-ready goldens AND re-verifies every golden pinned in test_2d_gldzm_mirp.h -- both -the per-slice table and the four-slice means -- exiting non-zero on any mismatch or on any pin this -generator cannot produce. +Prints the paste-ready goldens AND re-verifies every golden pinned in test_2d_gldzm_mirp.h -- the +per-slice table, the four-slice means and the negative-grey-depth table -- exiting non-zero on any +mismatch or on any pin this generator cannot produce. Recipe `gldzm.ibsi_phantom_2d`: the four IBSI digital-phantom slices, each featurised on its own. Each slice is its own ROI and yields its own scalar; their mean is what the IBSI "2D, averaged" @@ -18,13 +19,31 @@ over the 80 comparisons. That is why the header pins at SPEC 7's "exact" tier -- an ABSOLUTE 1e-9 band -- rather than at a cross-tool relative one. +Recipe `gldzm.mirp_fbn20_negdepth`, table gldzm_2d_mirp_negdepth_ref_vals: the negative coarse grey +depth. GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], which is +IBSI's fixed bin number, floor(20 (x - min) / (max - min)) + 1, and exactly what mirp's +`base_discretisation_method="fixed_bin_number"`, n_bins=20, computes. So mirp discretises here +itself: nothing of Nyxus' binning is reproduced on the mirp side, and the comparison covers the +binning as well as the zones and the feature formulas. The fixture is bench_square12_graded, built +by square12_graded.py (shared with gen_ngldm_mirp.py), `by_slice=True`. 14 of its 144 pixels sit +exactly on a bin edge at 20 bins, and the 5 at 181 are the ones a division by the bin width sends +one bin low; square12_graded.py has the arithmetic. Every run also checks that test_main_nyxus.h +still builds the square from the same formula. The pins are printed at full precision, so they are +held at rel 1e-12 -- a staleness check, not a vetting band. + +That table pins only the six features that read no zone's border distance -- GLNU, GLNUN, ZP, GLV, +LGLZE, HGLZE. The square fills its bounding box, so its border distance cannot tell the 2D distance +map from IBSI's, and pinning the distance features on it would claim more than it shows. + NOT covered here: GLDZM_GLM and GLDZM_ZDM. mirp exposes no grey-level-mean or zone-distance-mean column -- neither is an IBSI GLDZM feature -- so those two stay regression rows in test_2d_gldzm_regression.h. Provenance: tool=mirp (version printed by this script); numpy; env=nyxus_mirp (conda); -generator=tests/vetting/oracles/gen_gldzm_mirp.py. Run offline; CI never invokes it. +generator=tests/vetting/oracles/gen_gldzm_mirp.py, with tests/vetting/oracles/square12_graded.py. +Run offline; CI never invokes it. """ +import argparse import importlib.util import logging import os @@ -42,6 +61,8 @@ TEST_H = os.path.join(TESTS, "test_2d_gldzm_mirp.h") RELTOL = 1e-9 # this script's own golden-vs-mirp check, not the test tier; current run: rel = 0 +NEGDEPTH_RELTOL = 1e-12 # the negdepth pins are printed at %.17g; a staleness check, not a band +NEGDEPTH_TABLE = "gldzm_2d_mirp_negdepth_ref_vals" # Nyxus feature -> mirp column stem. mirp writes "zone" where Nyxus writes "zone level", and # abbreviates emphasis as lge/hge against Nyxus' LGLZE/HGLZE, so map by meaning, not by spelling. @@ -65,13 +86,22 @@ } -def phantom_slices(): - """The IBSI phantom, read out of tests/test_data.h by the shared helper.""" - spec = importlib.util.spec_from_file_location( - "ibsi_phantom", os.path.join(HERE, "ibsi_phantom.py")) +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) - return mod.phantom_slices() + return mod + + +def phantom_slices(): + """The IBSI phantom, read out of tests/test_data.h by the shared helper.""" + return _helper("ibsi_phantom").phantom_slices() + + +SQUARE = _helper("square12_graded") +NEGDEPTH_SCOPE = {k: MIRP_COLUMN[k] for k in + ("GLDZM_GLNU", "GLDZM_GLNUN", "GLDZM_ZP", "GLDZM_GLV", "GLDZM_LGLZE", "GLDZM_HGLZE")} def parse_pins(txt, table): @@ -124,7 +154,36 @@ def verify(pins, got, label): return nok, nfail, nmiss +def verify_negdepth(pins, got): + """-> (verified, failed, unproducible) for the negdepth table: scope and values both.""" + print("") + print(f"# verifying {len(pins)} goldens pinned in {NEGDEPTH_TABLE} against this run, " + f"at rel<={NEGDEPTH_RELTOL:g}") + nok = nfail = nmiss = 0 + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but is outside this table's scope") + nmiss += 1 + for name in sorted(set(got) - set(pins)): + print(f" FAIL {name}: mirp computes it in this table's scope and the header does not pin it") + nfail += 1 + for name in sorted(set(pins) & set(got)): + have, want = got[name][0], pins[name] + rel = abs(want - have) / max(abs(have), 1e-300) + if rel <= NEGDEPTH_RELTOL: + print(f" OK {name}: mirp={have!r} pinned={want!r} rel={rel:.3g}") + nok += 1 + else: + print(f" FAIL {name}: mirp={have!r} pinned={want!r} rel={rel:.3g}") + nfail += 1 + return nok, nfail, nmiss + + def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", + help="verify the pins without printing the paste-ready tables") + args = ap.parse_args() + try: version = metadata.version("mirp") # mirp exposes no __version__ except metadata.PackageNotFoundError: @@ -133,14 +192,25 @@ def main(): slices = run() means = {k: float(np.mean(v)) for k, v in slices.items()} by_slice = {f"{k}_z{z + 1}": v for k, vs in slices.items() for z, v in enumerate(vs)} - - print(f"# mirp {version}, numpy {np.__version__}, recipe gldzm.ibsi_phantom_2d") - print("# paste-ready goldens (mean over the four IBSI phantom slices)") - for name in sorted(means): - print(f'\t{{"{name}", {means[name]!r}}},') - print("# paste-ready per-slice goldens") - for name in sorted(by_slice): - print(f'\t{{"{name}", {by_slice[name]!r}}},') + negdepth = SQUARE.mirp_fbn("gldzm", NEGDEPTH_SCOPE) + + print(f"# mirp {version}, numpy {np.__version__}, " + f"recipes gldzm.ibsi_phantom_2d and gldzm.mirp_fbn20_negdepth") + if not args.check: + print("# paste-ready goldens (mean over the four IBSI phantom slices)") + for name in sorted(means): + print(f'\t{{"{name}", {means[name]!r}}},') + print("# paste-ready per-slice goldens") + for name in sorted(by_slice): + print(f'\t{{"{name}", {by_slice[name]!r}}},') + print("") + print(f"# paste-ready {NEGDEPTH_TABLE} (bench_square12_graded, fixed_bin_number n=20)") + print(f"static const ref_vals_map {NEGDEPTH_TABLE}{{") + items = list(negdepth.items()) + for i, (name, (v, col)) in enumerate(items): + sep = "," if i < len(items) - 1 else "" + print(f'\t\t{{ "{name}",\t{v!r} }}{sep}\t\t// {col}') + print("};") if not os.path.exists(TEST_H): print("") @@ -154,6 +224,12 @@ def main(): a, b, c = verify(parse_pins(text, "gldzm_2d_mirp_slice_ref_vals"), by_slice, "per-slice") nok, nfail, nmiss = nok + a, nfail + b, nmiss + c + SQUARE.check_square_in_header() + print("") + print("# test_main_nyxus.h builds bench_square12_graded from the same formula") + a, b, c = verify_negdepth(parse_pins(text, NEGDEPTH_TABLE), negdepth) + nok, nfail, nmiss = nok + a, nfail + b, nmiss + c + print("") print(f"{nok} verified, {nfail} failed, {nmiss} unproducible") if nfail or nmiss: diff --git a/tests/vetting/oracles/gen_ngldm3d_mirp.py b/tests/vetting/oracles/gen_ngldm3d_mirp.py index 45302ccd4..fc2a88c92 100644 --- a/tests/vetting/oracles/gen_ngldm3d_mirp.py +++ b/tests/vetting/oracles/gen_ngldm3d_mirp.py @@ -1,10 +1,11 @@ """OFFLINE MIRP oracle for the 3D NGLDM features, on the segmented phantom. - python tests/vetting/oracles/gen_ngldm3d_mirp.py (from the repository root) + python tests/vetting/oracles/gen_ngldm3d_mirp.py (from the repository root) + python tests/vetting/oracles/gen_ngldm3d_mirp.py --check (verify only, no paste-ready tables) -Runs MIRP twice and re-verifies both comparison tables in the vetting report, exiting non-zero on -any mismatch, on any quoted feature it cannot produce, and on any feature it produces that the report -does not quote. +Runs MIRP four times and re-verifies the three comparison tables in the vetting report and every +MIRP golden pinned in test_3d_ngldm_mirp.h, exiting non-zero on any mismatch, on any quoted feature +it cannot produce, and on any feature it produces that the report does not quote. - `ngldm3d.mirp_fbn64` -- MIRP discretises the ROI itself, `fixed_bin_number` n=64. The two sides land on different grey levels (below), so this table measures the discretisation gap. @@ -32,11 +33,23 @@ READ THIS BEFORE PINNING ANYTHING FROM THE fbn64 RUN: it is not a config-matched comparison. The matched one is samelevels. +`ngldm3d.mirp_fbn20_negdepth`, table ngldm_3d_mirp_negdepth_ref_vals: the negative coarse grey +depth. GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], which is +IBSI's fixed bin number, floor(20 (x - min) / (max - min)) + 1, and exactly what MIRP's +`base_discretisation_method="fixed_bin_number"`, n_bins=20, computes. So MIRP discretises here +itself and, unlike samelevels, nothing of Nyxus' binning is reproduced on the MIRP side: the table +covers the binning as well as the matrix. MIRP is handed `nyxus_raw_levels()`, the integer levels +Nyxus loads the float phantom as, which is the loader's step and not the binning. Over the ROI those +span 1024-3024, so the bin width is exactly 100: 2736 ROI voxels sit on an interior bin edge, and a +division by that width bins every one of them as IBSI does. The 2D square of gen_ngldm_mirp.py is +the fixture that separates the two formulas. The pins are printed at full precision, so they are +held at rel 1e-12 -- a staleness check, not a vetting band. + 3NGLDM_GLM (grey level mean) and 3NGLDM_DCM (dependence count mean) have no MIRP counterpart -- its NGLDM emits no gl_mean / dc_mean column -- so they cannot be vetted here at all. 3NGLDM_DCP is computed by both and deliberately not pinned: Nyxus hard-codes it to 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, so the check below allows exactly that one -omission and fails on any other. +omission and fails on any other; the negdepth table leaves it out for the same reason. NIFTI READING WITHOUT A NIFTI LIBRARY: the mirp env has neither SimpleITK nor nibabel. The phantoms are uncompressed single-file NIfTI-1 (magic "n+1"), so the header is parsed directly below and the @@ -48,6 +61,7 @@ `conda create -n nyxus_mirp -c conda-forge python=3.11 mirp numpy`); generator=tests/vetting/oracles/gen_ngldm3d_mirp.py. Run offline; CI never invokes it. """ +import argparse import logging import os import re @@ -70,6 +84,9 @@ RELTOL = 1e-5 LABEL = 57 NBINS = 64 +NEGDEPTH_NBINS = 20 +NEGDEPTH_RELTOL = 1e-12 # the negdepth pins are printed at %.17g; a staleness check, not a band +NEGDEPTH_TABLE = "ngldm_3d_mirp_negdepth_ref_vals" # Nyxus feature -> MIRP NGLDM column stem. MIRP suffixes every column with the neighbourhood and # discretisation it was computed at (`_d1_a0.0_3d_fbn_n64` when it discretises, `_d1_a0.0_3d` when it @@ -97,6 +114,8 @@ SUFFIX_FBN = f"_d1_a0.0_3d_fbn_n{NBINS}" SUFFIX_SAMELEVELS = "_d1_a0.0_3d" # MIRP drops the discretisation stem when there is none +SUFFIX_NEGDEPTH = f"_d1_a0.0_3d_fbn_n{NEGDEPTH_NBINS}" +NEGDEPTH_SCOPE = [k for k in MIRP if k != "3NGLDM_DCP"] NIFTI_DTYPE = {2: np.uint8, 4: np.int16, 8: np.int32, 16: np.float32, 64: np.float64} @@ -229,7 +248,13 @@ def features(image, suffix, **discretisation): raw = np.where(m, nyxus_raw_levels(inten), 0).astype(np.float64) ibsi = features(raw, SUFFIX_SAMELEVELS, base_discretisation_method="none") print(f"# ibsi=true grey levels over the roi: {int(np.unique(raw[m]).size)} distinct raw values") - return (fbn, same, ibsi), span + + # The negative grey depth: MIRP bins the loader-shifted levels itself, at 20 bins. + neg = features(nyxus_raw_levels(inten).astype(np.float64), SUFFIX_NEGDEPTH, + base_discretisation_method="fixed_bin_number", + base_discretisation_n_bins=NEGDEPTH_NBINS) + neg = {k: neg[k] for k in NEGDEPTH_SCOPE} + return (fbn, same, ibsi, neg), span def verify(got, heading, txt, pins, derived, bound): @@ -288,12 +313,17 @@ def verify(got, heading, txt, pins, derived, bound): def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", + help="verify the report and the pins without printing the paste-ready tables") + args = ap.parse_args() + for p in (INTEN, MASK): if not os.path.exists(p): print(f"missing phantom: {p}") return 1 - (fbn, same, ibsi), span = run() + (fbn, same, ibsi, neg), span = run() try: version = metadata.version("mirp") # mirp exposes no __version__ @@ -304,13 +334,20 @@ def main(): # provenance of the values printed below it, so a run under another version has to say so. print(f"# mirp {version}, numpy {np.__version__}, label={LABEL}, by_slice=False, " f"distance=1, alpha=0") - for title, got, suffix in (("ngldm3d.mirp_fbn64", fbn, SUFFIX_FBN), - ("ngldm3d.mirp_samelevels", same, SUFFIX_SAMELEVELS), - ("ngldm3d.mirp_ibsi_rawlevels", ibsi, SUFFIX_SAMELEVELS)): - print(f"\n# {title}") - for name in sorted(got): - print(f'\t{{"{name}", {got[name]!r}}},'.ljust(56) + f"// {MIRP[name]}{suffix}") - print("\n# no MIRP counterpart at either recipe: 3NGLDM_GLM, 3NGLDM_DCM") + if not args.check: + for title, got, suffix in (("ngldm3d.mirp_fbn64", fbn, SUFFIX_FBN), + ("ngldm3d.mirp_samelevels", same, SUFFIX_SAMELEVELS), + ("ngldm3d.mirp_ibsi_rawlevels", ibsi, SUFFIX_SAMELEVELS)): + print(f"\n# {title}") + for name in sorted(got): + print(f'\t{{"{name}", {got[name]!r}}},'.ljust(56) + f"// {MIRP[name]}{suffix}") + print("\n# ngldm3d.mirp_fbn20_negdepth, paste-ready") + print(f"static const ref_vals_map {NEGDEPTH_TABLE}{{") + for i, name in enumerate(NEGDEPTH_SCOPE): + sep = "," if i < len(NEGDEPTH_SCOPE) - 1 else "" + print(f'\t\t{{ "{name}",\t{neg[name]!r} }}{sep}\t\t// {MIRP[name]}{SUFFIX_NEGDEPTH}') + print("};") + print("\n# no MIRP counterpart at any recipe: 3NGLDM_GLM, 3NGLDM_DCM") if not os.path.exists(REPORT): print(f"\n# {os.path.basename(REPORT)} is missing -- there is nothing this run can be " @@ -373,6 +410,27 @@ def main(): print(f" FAIL {name}: MIRP computes it and {table} does not pin it") nfail += 1 + # The negdepth goldens are MIRP's own binning at 20 bins, printed at full precision, so they are + # held to a staleness tolerance and their scope is checked in both directions. + neg_pins = parse_pins(MIRP_H, NEGDEPTH_TABLE) + print(f"\n# verifying the {len(neg_pins)} goldens pinned in {NEGDEPTH_TABLE} against this run, " + f"at rel<={NEGDEPTH_RELTOL:g}") + for name in sorted(set(neg_pins) - set(neg)): + print(f" MISSING {name}: pinned {neg_pins[name]!r} but is outside this table's scope") + nmiss += 1 + for name in sorted(set(neg) - set(neg_pins)): + print(f" FAIL {name}: MIRP computes it in this table's scope and {NEGDEPTH_TABLE} does " + f"not pin it") + nfail += 1 + for name in sorted(set(neg_pins) & set(neg)): + rel = abs(neg_pins[name] - neg[name]) / max(abs(neg[name]), 1e-300) + if rel <= NEGDEPTH_RELTOL: + print(f" OK {name}: pin={neg_pins[name]!r} mirp={neg[name]!r} rel={rel:.3g}") + nok += 1 + else: + print(f" FAIL {name}: pin={neg_pins[name]!r} mirp={neg[name]!r} rel={rel:.3g}") + nfail += 1 + # the grey-level span is the report's explanation of the fbn64 gap, so it is checked too span_txt = f"{span[0]}-{span[1]}, {span[2]} distinct" if span_txt not in txt: diff --git a/tests/vetting/oracles/gen_ngldm_mirp.py b/tests/vetting/oracles/gen_ngldm_mirp.py index cda0a6253..336b5937f 100644 --- a/tests/vetting/oracles/gen_ngldm_mirp.py +++ b/tests/vetting/oracles/gen_ngldm_mirp.py @@ -1,9 +1,10 @@ -"""OFFLINE mirp oracle for the 2D NGLDM features, on the IBSI digital phantom. +"""OFFLINE mirp oracle for the 2D NGLDM features, on the IBSI digital phantom and bench_square12_graded. - python tests/vetting/oracles/gen_ngldm_mirp.py (from the repository root) + python tests/vetting/oracles/gen_ngldm_mirp.py (from the repository root) + python tests/vetting/oracles/gen_ngldm_mirp.py --check (verify only, no paste-ready tables) -Prints the paste-ready goldens AND re-verifies every golden pinned in test_2d_ngldm_mirp.h, exiting -non-zero on any mismatch or on any pin this generator cannot produce. +Prints the paste-ready goldens of both recipes AND re-verifies every golden pinned in +test_2d_ngldm_mirp.h, exiting non-zero on any mismatch or on any pin this generator cannot produce. Recipe `ngldm.ibsi_phantom_2d`: the four IBSI digital-phantom slices, each featurised on its own and the per-feature values averaged over the four, which is what test_2d_ngldm_common.h's fixture does. @@ -16,13 +17,28 @@ consensus values in test_2d_ngldm_ibsi.h are the same quantities quoted to three significant figures, which is why that file asserts at rel=1e-2 while this one asserts at 1e-9. +Recipe `ngldm.mirp_fbn20_negdepth`, table ngldm_2d_mirp_negdepth_ref_vals: the negative coarse grey +depth. GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], which is +IBSI's fixed bin number, floor(20 (x - min) / (max - min)) + 1, and exactly what mirp's +`base_discretisation_method="fixed_bin_number"`, n_bins=20, computes. So mirp discretises here +itself: nothing of Nyxus' binning is reproduced on the mirp side, and the comparison covers the +binning as well as the matrix and the feature formulas. The fixture is bench_square12_graded, built +by square12_graded.py (shared with gen_gldzm_mirp.py), `by_slice=True`, distance 1, difference +level 0. 14 of its 144 pixels sit exactly on a bin edge at 20 bins, and the 5 at 181 are the ones a +division by the bin width sends one bin low; square12_graded.py has the arithmetic. Every run also +checks that test_main_nyxus.h still builds the square from the same formula. NGLDM_DCP is left out +of this table: both tools return 1 whenever every pixel has a same-level neighbour. The pins are +printed at full precision, so they are held at rel 1e-12 -- a staleness check, not a vetting band. + NOT covered here: NGLDM_GLM and NGLDM_DCM. mirp exposes no grey-level-mean or dependence-count-mean column -- they are not IBSI NGLDM features -- so those two stay regression rows in test_2d_ngldm_regression.h. Provenance: tool=mirp (version printed by this script); numpy; env=nyxus_mirp (conda); -generator=tests/vetting/oracles/gen_ngldm_mirp.py. Run offline; CI never invokes it. +generator=tests/vetting/oracles/gen_ngldm_mirp.py, with tests/vetting/oracles/square12_graded.py. +Run offline; CI never invokes it. """ +import argparse import importlib.util import logging import os @@ -41,6 +57,8 @@ TEST_H = os.path.join(TESTS, "test_2d_ngldm_mirp.h") RELTOL = 1e-9 # SPEC 7 exact tier; measured worst residual is 2.9e-16 +NEGDEPTH_RELTOL = 1e-12 # the negdepth pins are printed at %.17g; a staleness check, not a band +NEGDEPTH_TABLE = "ngldm_2d_mirp_negdepth_ref_vals" # Nyxus feature -> mirp column stem (mirp suffixes the discretisation/config, e.g. _d1_a0.0_2d) MIRP_COLUMN = { @@ -56,13 +74,21 @@ } -def phantom_slices(): - """The IBSI phantom, read out of tests/test_data.h by the shared helper.""" - spec = importlib.util.spec_from_file_location( - "ibsi_phantom", os.path.join(HERE, "ibsi_phantom.py")) +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) - return mod.phantom_slices() + return mod + + +def phantom_slices(): + """The IBSI phantom, read out of tests/test_data.h by the shared helper.""" + return _helper("ibsi_phantom").phantom_slices() + + +SQUARE = _helper("square12_graded") +NEGDEPTH_SCOPE = {k: v for k, v in MIRP_COLUMN.items() if k != "NGLDM_DCP"} def parse_pins(txt, table): @@ -94,27 +120,69 @@ def run(): return {k: float(np.mean(v)) for k, v in per_slice.items()} +def verify_negdepth(pins, got): + """-> (verified, failed, unproducible) for the negdepth table: scope and values both.""" + print(f"\n# verifying {len(pins)} goldens pinned in {NEGDEPTH_TABLE} against this run, " + f"at rel<={NEGDEPTH_RELTOL:g}") + nok = nfail = nmiss = 0 + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but is outside this table's scope") + nmiss += 1 + for name in sorted(set(got) - set(pins)): + print(f" FAIL {name}: mirp computes it in this table's scope and the header does not pin it") + nfail += 1 + for name in sorted(set(pins) & set(got)): + have, want = got[name][0], pins[name] + rel = abs(want - have) / max(abs(have), 1e-300) + if rel <= NEGDEPTH_RELTOL: + print(f" OK {name}: mirp={have!r} pinned={want!r} rel={rel:.3g}") + nok += 1 + else: + print(f" FAIL {name}: mirp={have!r} pinned={want!r} rel={rel:.3g}") + nfail += 1 + return nok, nfail, nmiss + + def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", + help="verify the pins without printing the paste-ready tables") + args = ap.parse_args() + try: version = metadata.version("mirp") # mirp exposes no __version__ except metadata.PackageNotFoundError: version = "unknown" got = run() - - print(f"# mirp {version}, numpy {np.__version__}, recipe ngldm.ibsi_phantom_2d") - print("# paste-ready goldens (mean over the four IBSI phantom slices)") - for name in sorted(got): - print(f'\t{{"{name}", {got[name]!r}}},') + negdepth = SQUARE.mirp_fbn("ngldm", NEGDEPTH_SCOPE) + + print(f"# mirp {version}, numpy {np.__version__}, " + f"recipes ngldm.ibsi_phantom_2d and ngldm.mirp_fbn20_negdepth") + if not args.check: + print("# paste-ready goldens (mean over the four IBSI phantom slices)") + for name in sorted(got): + print(f'\t{{"{name}", {got[name]!r}}},') + print(f"\n# paste-ready {NEGDEPTH_TABLE} (bench_square12_graded, fixed_bin_number n=20)") + print(f"static const ref_vals_map {NEGDEPTH_TABLE}{{") + items = list(negdepth.items()) + for i, (name, (v, col)) in enumerate(items): + sep = "," if i < len(items) - 1 else "" + print(f'\t\t{{ "{name}",\t{v!r} }}{sep}\t\t// {col}') + print("};") if not os.path.exists(TEST_H): print(f"\n{os.path.basename(TEST_H)} does not exist yet - nothing to verify") return 0 - pins = parse_pins(open(TEST_H, encoding="utf-8", errors="replace").read(), - "ngldm_2d_mirp_ref_vals") + text = open(TEST_H, encoding="utf-8", errors="replace").read() + SQUARE.check_square_in_header() + print("\n# test_main_nyxus.h builds bench_square12_graded from the same formula") + neg_ok, neg_fail, neg_miss = verify_negdepth(parse_pins(text, NEGDEPTH_TABLE), negdepth) + + pins = parse_pins(text, "ngldm_2d_mirp_ref_vals") print(f"\n# verifying {len(pins)} pinned goldens against this run") - nok = nfail = nmiss = 0 + nok, nfail, nmiss = neg_ok, neg_fail, neg_miss for name in sorted(pins): want = pins[name] if name not in got: diff --git a/tests/vetting/oracles/square12_graded.py b/tests/vetting/oracles/square12_graded.py new file mode 100644 index 000000000..45b5882a0 --- /dev/null +++ b/tests/vetting/oracles/square12_graded.py @@ -0,0 +1,90 @@ +"""bench_square12_graded, the 2D fixture of the negative coarse grey depth, and MIRP's run on it. + +A 12x12 ROI in a 14x14 frame at levels 100 + 3 ((7x + 11y + xy) mod 37), 36 of them over 100-208. +tests/test_main_nyxus.h builds it for the C++ tests (`make_2d_square12_graded_phantom`); this module +builds the same array for MIRP, and `check_square_in_header()` fails if the header's formula is no +longer the one below. gen_ngldm_mirp.py and gen_gldzm_mirp.py both pin MIRP on it and both load it +from here, so there is one Python copy of the fixture. + +At 20 PyRadiomics-style bins (range 108, bin width 5.4) the interior bin edges fall at 127, 154 and +181, and 14 of its 144 pixels sit exactly on one: 5 at 127, 4 at 154, 5 at 181. IBSI's fixed bin +number, floor(n (x - min) / (max - min)) + 1, puts each in the bin above its edge, as MIRP does. A +division by the bin width, floor((x - min) / ((max - min) / n)) + 1, agrees at 127 and 154, and the +5 at 181 are the ones it sends one bin low: (181 - 100) / 5.4 lands just under 15 in floating point. + +numpy is the only dependency at import; MIRP is imported by `mirp_fbn()` alone. +""" +import logging +import os +import re + +import numpy as np + +HERE = os.path.dirname(os.path.abspath(__file__)) +TESTS = os.path.dirname(os.path.dirname(HERE)) +MAIN_H = os.path.join(TESTS, "test_main_nyxus.h") + +SIDE, LO, HI = 14, 1, 12 +NBINS = 20 + + +def square12_graded(): + """-> (intensity, mask) of bench_square12_graded, as tests/test_main_nyxus.h builds it.""" + img = np.zeros((SIDE, SIDE), np.float64) + msk = np.zeros((SIDE, SIDE), np.int32) + for y in range(SIDE): + for x in range(SIDE): + if LO <= x <= HI and LO <= y <= HI: + xx, yy = x - LO, y - LO + img[y, x] = 100 + 3 * ((7 * xx + 11 * yy + xx * yy) % 37) + msk[y, x] = 1 + return img, msk + + +def check_square_in_header(): + """The C++ fixture must be the array MIRP is fed: compare the formula's text.""" + src = open(MAIN_H, encoding="utf-8").read() + m = re.search(r"make_2d_square12_graded_phantom.*?\{(.*?)\n \}", src, re.S) + if not m: + raise RuntimeError("no make_2d_square12_graded_phantom in test_main_nyxus.h") + body = re.sub(r"\s+", "", m.group(1)) + for frag in ("side=14", "lo=1", "hi=12", "100+3*((7*xx+11*yy+xx*yy)%37)"): + if frag not in body: + raise RuntimeError(f"test_main_nyxus.h's square no longer carries {frag!r}") + + +def mirp_fbn(family, mapping): + """-> {Nyxus feature: (value, MIRP column)} for MIRP's `family` on the square. + + `base_discretisation_method="fixed_bin_number"`, n_bins=20, `by_slice=True`: MIRP bins the ROI + itself, so nothing of Nyxus' binning is reproduced here. `mapping` is Nyxus feature -> MIRP column + stem; each stem has to resolve to exactly one column at this configuration. + """ + import mirp + logging.disable(logging.INFO) + + img, msk = square12_graded() + res = mirp.extract_features( + image=img[np.newaxis], mask=msk[np.newaxis], image_spacing=(1.0, 1.0, 1.0), by_slice=True, + base_feature_families=family, base_discretisation_method="fixed_bin_number", + base_discretisation_n_bins=NBINS) + row = (res[0] if isinstance(res, list) else res).iloc[0] + out = {} + for nyx, stem in mapping.items(): + pat = re.compile(re.escape(stem) + r"_(d1_a0\.0_)?2d" + f"_fbn_n{NBINS}$") + cols = [c for c in row.index if pat.match(c)] + if len(cols) != 1: + raise RuntimeError(f"{nyx}: expected one MIRP column for {stem}, found {cols}") + out[nyx] = (float(row[cols[0]]), cols[0]) + return out + + +if __name__ == "__main__": + img, msk = square12_graded() + roi = img[msk > 0] + lo, hi = roi.min(), roi.max() + on_edge = roi[(NBINS * (roi - lo)) % (hi - lo) == 0] + on_edge = on_edge[(on_edge > lo) & (on_edge < hi)] + print(f"{int(msk.sum())} ROI pixels, {np.unique(roi).size} levels over {lo:g}-{hi:g}; " + f"on an interior edge at {NBINS} bins: " + + ", ".join(f"{int(c)} at {v:g}" for v, c in zip(*np.unique(on_edge, return_counts=True)))) diff --git a/tests/vetting/report_output.csv b/tests/vetting/report_output.csv index c860474c8..379782761 100644 --- a/tests/vetting/report_output.csv +++ b/tests/vetting/report_output.csv @@ -297,19 +297,25 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 2D,glrlm,GLRLM_LRHGLE_AVE,vetted,ibsi,glrlm.ibsi_ng128,rel=1e-9,agreed,,,,,in-tree,ibsi;mirp;pyradiomics,test_2d_glrlm_family_mirp;test_2d_glrlm_family_pyradiomics;test_2d_glrlm_lrhgle_ave_ibsi,test_2d_glrlm_lrhgle_ave_regression,,3,1,"angle average; the tools report one value over the 4 directions, so it shares its base feature's golden",,agree,feature,audit/glrlm_2d_ibsi_vetting_report.md,audit/glrlm_2d_golden_regen.md,,"Angle average of GLRLM_LRHGLE, asserted per slice against the same golden as its base. Asserted on the IBSI digital phantom in test_2d_glrlm_ibsi.h (IBSI consensus), test_2d_glrlm_pyradiomics.h (pyradiomics v3.0.1) and test_2d_glrlm_mirp.h (mirp 2.6.0) at rel<=rel=1e-9; the two tools agree with each other to ~1e-15 and Nyxus reproduces them to double precision. Was vetted from an offline run only (source=tracker), with target_test naming a file that did not exist. Evidence: tests/vetting/audit/glrlm_2d_*_vetting_report.md. | vetted vs IBSI digital-phantom consensus (GLRLM LRHGLE = 17.4) at 1% in test_2d_glrlm_ibsi.h, ibsi=True Ng=128, averaged over the 4 phantom slices x 4 directions (_AVE direction-mean, same grand mean). IBSI is the reference table (§4); no tool run at CI time. CONFIG SCOPE (measured): ibsi=true gives 17.387 (matches the IBSI reference); ibsi=false gives 7358.78 on the same fixture -- default-mode values are NOT vetted." 2D,gldzm,GLDZM_SDE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_SDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_SDE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_sde_ibsi;test_2d_gldzm_sde_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_sde_ibsi;test_2d_gldzm_sde_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_LDE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_LDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_lde_ibsi;test_2d_gldzm_lde_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_lde_ibsi;test_2d_gldzm_lde_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" -2D,gldzm,GLDZM_LGLZE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_LGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LGLZE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_lglze_ibsi;test_2d_gldzm_lglze_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_lglze_ibsi;test_2d_gldzm_lglze_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" -2D,gldzm,GLDZM_HGLZE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_HGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_HGLZE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_hglze_ibsi;test_2d_gldzm_hglze_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_hglze_ibsi;test_2d_gldzm_hglze_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_LGLZE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_LGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LGLZE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_lglze_ibsi;test_2d_gldzm_lglze_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_lglze_ibsi;test_2d_gldzm_lglze_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_LGLZE,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_lglze_ibsi;test_2d_gldzm_lglze_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." +2D,gldzm,GLDZM_HGLZE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_HGLZE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_HGLZE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_hglze_ibsi;test_2d_gldzm_hglze_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_hglze_ibsi;test_2d_gldzm_hglze_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_HGLZE,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_hglze_ibsi;test_2d_gldzm_hglze_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." 2D,gldzm,GLDZM_SDLGLE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_SDLGLE_MIRP,,,audit,mirp,test_2d_gldzm_sdlgle_mirp,,,1,0,vetted by mirp only; the IBSI file never held a published value for it,test_2d_gldzm_sdlgle_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_SDHGLE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_SDHGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_SDHGLE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_sdhgle_ibsi;test_2d_gldzm_sdhgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_sdhgle_ibsi;test_2d_gldzm_sdhgle_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_LDLGLE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_LDLGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDLGLE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_ldlgle_ibsi;test_2d_gldzm_ldlgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_ldlgle_ibsi;test_2d_gldzm_ldlgle_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_LDHGLE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_LDHGLE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_LDHGLE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_ldhgle_ibsi;test_2d_gldzm_ldhgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_ldhgle_ibsi;test_2d_gldzm_ldhgle_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" -2D,gldzm,GLDZM_GLNU,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLNU_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNU_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glnu_ibsi;test_2d_gldzm_glnu_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glnu_ibsi;test_2d_gldzm_glnu_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" -2D,gldzm,GLDZM_GLNUN,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLNUN_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNUN_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glnun_ibsi;test_2d_gldzm_glnun_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glnun_ibsi;test_2d_gldzm_glnun_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_GLNU,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLNU_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNU_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glnu_ibsi;test_2d_gldzm_glnu_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glnu_ibsi;test_2d_gldzm_glnu_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_GLNU,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_glnu_ibsi;test_2d_gldzm_glnu_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." +2D,gldzm,GLDZM_GLNUN,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLNUN_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLNUN_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glnun_ibsi;test_2d_gldzm_glnun_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glnun_ibsi;test_2d_gldzm_glnun_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_GLNUN,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_glnun_ibsi;test_2d_gldzm_glnun_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." 2D,gldzm,GLDZM_ZDNU,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZDNU_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDNU_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_zdnu_ibsi;test_2d_gldzm_zdnu_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_zdnu_ibsi;test_2d_gldzm_zdnu_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_ZDNUN,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZDNUN_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDNUN_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_zdnun_ibsi;test_2d_gldzm_zdnun_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_zdnun_ibsi;test_2d_gldzm_zdnun_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" -2D,gldzm,GLDZM_ZP,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZP_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZP_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_zp_ibsi;test_2d_gldzm_zp_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_zp_ibsi;test_2d_gldzm_zp_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_ZP,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZP_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZP_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_negative_greydepth_mirp;test_2d_gldzm_zp_ibsi;test_2d_gldzm_zp_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_zp_ibsi;test_2d_gldzm_zp_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_ZP,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_negative_greydepth_mirp;test_2d_gldzm_zp_ibsi;test_2d_gldzm_zp_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." 2D,gldzm,GLDZM_GLM,regression,,gldzm.ibsi_phantom_2d,rel=1e-3,,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLM_REGRESSION,,,audit,,,test_2d_gldzm_glm_regression,,0,1,no IBSI GLDZM counterpart and no mirp column; regression drift guard only,test_2d_gldzm_glm_regression,agree,row,,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"not an IBSI GLDZM feature and mirp exposes no column for it, so nothing independent covers it; drift-pinned on the IBSI phantom in test_2d_gldzm_regression.h at rel=1e-3. Value re-recorded after the zone-connectivity fix (8-connected zones), see audit/gldzm_2d_mirp_vetting_report.md" -2D,gldzm,GLDZM_GLV,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLV_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLV_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glv_ibsi;test_2d_gldzm_glv_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glv_ibsi;test_2d_gldzm_glv_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_GLV,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_GLV_IBSI;TEST_NYXUS.TEST_2D_GLDZM_GLV_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_glv_ibsi;test_2d_gldzm_glv_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_glv_ibsi;test_2d_gldzm_glv_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" +2D,gldzm,GLDZM_GLV,vetted,mirp,gldzm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_gldzm_glv_ibsi;test_2d_gldzm_glv_mirp;test_2d_gldzm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_negative_greydepth_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True. Only the six features that read no zone's border distance are pinned: the square fills its bounding box, so its border distance cannot tell the 2D distance map from IBSI's, which part on ROIs with background inside them. Measured residual 6.2e-16 worst case over the family; asserted at rel=1e-9 in test_2d_gldzm_mirp.h. gen_gldzm_mirp.py re-verifies every pin." 2D,gldzm,GLDZM_ZDM,regression,,gldzm.ibsi_phantom_2d,rel=1e-3,,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZDM_REGRESSION,,,audit,,,test_2d_gldzm_zdm_regression,,0,1,no IBSI GLDZM counterpart and no mirp column; regression drift guard only,test_2d_gldzm_zdm_regression,agree,row,,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"not an IBSI GLDZM feature and mirp exposes no column for it, so nothing independent covers it; drift-pinned on the IBSI phantom in test_2d_gldzm_regression.h at rel=1e-3. Value re-recorded after the zone-connectivity fix (8-connected zones), see audit/gldzm_2d_mirp_vetting_report.md" 2D,gldzm,GLDZM_ZDV,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZDV_MIRP,,,audit,mirp,test_2d_gldzm_zdv_mirp,,,1,0,vetted by mirp only; the IBSI file never held a published value for it,test_2d_gldzm_zdv_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" 2D,gldzm,GLDZM_ZDE,vetted,mirp,gldzm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDZM_ZDE_IBSI;TEST_NYXUS.TEST_2D_GLDZM_ZDE_MIRP,,,audit,ibsi;mirp,test_2d_gldzm_zde_ibsi;test_2d_gldzm_zde_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 1.3e-15 absolute",test_2d_gldzm_zde_ibsi;test_2d_gldzm_zde_mirp,agree,row,audit/gldzm_2d_mirp_vetting_report.md,audit/gldzm_2d_golden_regen.md,matrix/gldzm.md,"vetted vs mirp 2.6.0 on the four IBSI phantom slices (by_slice, no discretisation - the phantom is already discrete 1..6), recipe gldzm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: mirp computes each slice on its own, so both quantities are pinned in test_2d_gldzm_mirp.h at SPEC 7's exact tier, an absolute 1e-9 band (worst absolute residual 1.3e-15 over the 16 features x 4 slices plus the 16 means; worst relative 7.0e-16). The mean alone is blind to errors in two slices that cancel, which is the shape this family's zone connectivity defect actually took. The same means are pinned against the published IBSI consensus in test_2d_gldzm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to (worst residual there 0.35%). gen_gldzm_mirp.py" @@ -343,25 +349,41 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 2D,gldm,GLDM_SDHGLE,vetted,pyradiomics,gldm.ibsi_phantom_2d,rel=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDM_SDHGLE_PYRADIOMICS,,,audit,ibsi;pyradiomics,test_2d_gldm_sdhgle_ibsi;test_2d_gldm_sdhgle_pyradiomics,test_2d_gldm_sdhgle_regression,,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, pyradiomics fixes the digits at 1.6e-16",test_2d_gldm_sdhgle_pyradiomics,agree,row,audit/gldm_2d_pyradiomics_vetting_report.md,audit/gldm_2d_golden_regen.md,matrix/gldm.md,"vetted vs pyradiomics v3.0.1 GLDM on the four IBSI phantom slices (binWidth=1 identity binning, gldm_a=0, distances=[1], force2D), recipe gldm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: pyradiomics computes each slice on its own, so both quantities are pinned in test_2d_gldm_pyradiomics.h at rel=1e-9 (worst residual 1.0e-15 over the 14 features x 4 slices). The mean alone is blind to errors in two slices that cancel. The same means are pinned against the published IBSI consensus in test_2d_gldm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to; IBSI publishes them under the NGLDM name because a GLDM dependence count is IBSI's j = k + 1 at alpha=0, d=1. The production config (ibsi=false, MATLAB binning) is not comparable to pyradiomics and is drift-pinned only in test_2d_gldm_regression.h. gen_gldm_pyradiomics.py" 2D,gldm,GLDM_LDLGLE,vetted,pyradiomics,gldm.ibsi_phantom_2d,rel=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDM_LDLGLE_PYRADIOMICS,,,audit,ibsi;pyradiomics,test_2d_gldm_ldlgle_ibsi;test_2d_gldm_ldlgle_pyradiomics,test_2d_gldm_ldlgle_regression,,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, pyradiomics fixes the digits at 1.6e-16",test_2d_gldm_ldlgle_pyradiomics,agree,row,audit/gldm_2d_pyradiomics_vetting_report.md,audit/gldm_2d_golden_regen.md,matrix/gldm.md,"vetted vs pyradiomics v3.0.1 GLDM on the four IBSI phantom slices (binWidth=1 identity binning, gldm_a=0, distances=[1], force2D), recipe gldm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: pyradiomics computes each slice on its own, so both quantities are pinned in test_2d_gldm_pyradiomics.h at rel=1e-9 (worst residual 1.0e-15 over the 14 features x 4 slices). The mean alone is blind to errors in two slices that cancel. The same means are pinned against the published IBSI consensus in test_2d_gldm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to; IBSI publishes them under the NGLDM name because a GLDM dependence count is IBSI's j = k + 1 at alpha=0, d=1. The production config (ibsi=false, MATLAB binning) is not comparable to pyradiomics and is drift-pinned only in test_2d_gldm_regression.h. gen_gldm_pyradiomics.py" 2D,gldm,GLDM_LDHGLE,vetted,pyradiomics,gldm.ibsi_phantom_2d,rel=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_GLDM_LDHGLE_PYRADIOMICS,,,audit,ibsi;pyradiomics,test_2d_gldm_ldhgle_ibsi;test_2d_gldm_ldhgle_pyradiomics,test_2d_gldm_ldhgle_regression,,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, pyradiomics fixes the digits at 1.6e-16",test_2d_gldm_ldhgle_pyradiomics,agree,row,audit/gldm_2d_pyradiomics_vetting_report.md,audit/gldm_2d_golden_regen.md,matrix/gldm.md,"vetted vs pyradiomics v3.0.1 GLDM on the four IBSI phantom slices (binWidth=1 identity binning, gldm_a=0, distances=[1], force2D), recipe gldm.ibsi_phantom_2d. Backed per slice AND by the four-slice mean: pyradiomics computes each slice on its own, so both quantities are pinned in test_2d_gldm_pyradiomics.h at rel=1e-9 (worst residual 1.0e-15 over the 14 features x 4 slices). The mean alone is blind to errors in two slices that cancel. The same means are pinned against the published IBSI consensus in test_2d_gldm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to; IBSI publishes them under the NGLDM name because a GLDM dependence count is IBSI's j = k + 1 at alpha=0, d=1. The production config (ibsi=false, MATLAB binning) is not comparable to pyradiomics and is drift-pinned only in test_2d_gldm_regression.h. gen_gldm_pyradiomics.py" -2D,ngldm,NGLDM_LDE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_lde_ibsi;test_2d_ngldm_lde_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_HDE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hde_ibsi;test_2d_ngldm_hde_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_LGLCE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_lglce_ibsi;test_2d_ngldm_lglce_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_HGLCE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hglce_ibsi;test_2d_ngldm_hglce_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_LDLGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_ldlgle_ibsi;test_2d_ngldm_ldlgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_LDHGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_ldhgle_ibsi;test_2d_ngldm_ldhgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_HDLGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hdlgle_ibsi;test_2d_ngldm_hdlgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_HDHGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hdhgle_ibsi;test_2d_ngldm_hdhgle_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_GLNU,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glnu_ibsi;test_2d_ngldm_glnu_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_GLNUN,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glnun_ibsi;test_2d_ngldm_glnun_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_DCNU,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcnu_ibsi;test_2d_ngldm_dcnu_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_DCNUN,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcnun_ibsi;test_2d_ngldm_dcnun_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_LDE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_lde_ibsi;test_2d_ngldm_lde_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_LDE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_lde_ibsi;test_2d_ngldm_lde_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_HDE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hde_ibsi;test_2d_ngldm_hde_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_HDE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_hde_ibsi;test_2d_ngldm_hde_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_LGLCE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_lglce_ibsi;test_2d_ngldm_lglce_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_LGLCE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_lglce_ibsi;test_2d_ngldm_lglce_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_HGLCE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hglce_ibsi;test_2d_ngldm_hglce_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_HGLCE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_hglce_ibsi;test_2d_ngldm_hglce_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_LDLGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_ldlgle_ibsi;test_2d_ngldm_ldlgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_LDLGLE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_ldlgle_ibsi;test_2d_ngldm_ldlgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_LDHGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_ldhgle_ibsi;test_2d_ngldm_ldhgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_LDHGLE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_ldhgle_ibsi;test_2d_ngldm_ldhgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_HDLGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hdlgle_ibsi;test_2d_ngldm_hdlgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_HDLGLE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_hdlgle_ibsi;test_2d_ngldm_hdlgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_HDHGLE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_hdhgle_ibsi;test_2d_ngldm_hdhgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_HDHGLE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_hdhgle_ibsi;test_2d_ngldm_hdhgle_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_GLNU,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glnu_ibsi;test_2d_ngldm_glnu_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_GLNU,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_glnu_ibsi;test_2d_ngldm_glnu_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_GLNUN,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glnun_ibsi;test_2d_ngldm_glnun_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_GLNUN,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_glnun_ibsi;test_2d_ngldm_glnun_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_DCNU,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcnu_ibsi;test_2d_ngldm_dcnu_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCNU,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_dcnu_ibsi;test_2d_ngldm_dcnu_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_DCNUN,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcnun_ibsi;test_2d_ngldm_dcnun_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCNUN,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_dcnun_ibsi;test_2d_ngldm_dcnun_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." 2D,ngldm,NGLDM_DCP,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcp_ibsi;test_2d_ngldm_dcp_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" 2D,ngldm,NGLDM_GLM,regression,,ngldm.ibsi_phantom_2d,rel=1e-9,disagrees,,,,,audit,,,test_2d_ngldm_glm_regression,,0,1,no IBSI NGLDM counterpart and no mirp column; regression drift guard only,,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"regression: a Nyxus mean-style row with no IBSI NGLDM counterpart and no mirp column (mirp exposes no grey-level-mean or dependence-count-mean), so no oracle can reproduce it. Drift-pinned at rel=1e-9 in test_2d_ngldm_regression.h. The previous row claimed oracle=mirp and targeted a test_2d_ngldm_mirp.h that did not exist." -2D,ngldm,NGLDM_GLV,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glv_ibsi;test_2d_ngldm_glv_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_GLV,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_glv_ibsi;test_2d_ngldm_glv_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_GLV,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_glv_ibsi;test_2d_ngldm_glv_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." 2D,ngldm,NGLDM_DCM,regression,,ngldm.ibsi_phantom_2d,rel=1e-9,disagrees,,,,,audit,,,test_2d_ngldm_dcm_regression,,0,1,no IBSI NGLDM counterpart and no mirp column; regression drift guard only,,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"regression: a Nyxus mean-style row with no IBSI NGLDM counterpart and no mirp column (mirp exposes no grey-level-mean or dependence-count-mean), so no oracle can reproduce it. Drift-pinned at rel=1e-9 in test_2d_ngldm_regression.h. The previous row claimed oracle=mirp and targeted a test_2d_ngldm_mirp.h that did not exist." -2D,ngldm,NGLDM_DCV,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcv_ibsi;test_2d_ngldm_dcv_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_DCENT,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcent_ibsi;test_2d_ngldm_dcent_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" -2D,ngldm,NGLDM_DCENE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcene_ibsi;test_2d_ngldm_dcene_mirp,,,2,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCV,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcv_ibsi;test_2d_ngldm_dcv_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCV,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_dcv_ibsi;test_2d_ngldm_dcv_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_DCENT,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcent_ibsi;test_2d_ngldm_dcent_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCENT,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_dcent_ibsi;test_2d_ngldm_dcent_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." +2D,ngldm,NGLDM_DCENE,vetted,mirp,ngldm.ibsi_phantom_2d,rel=1e-9,agreed,,,,,audit,ibsi;mirp,test_2d_ngldm_dcene_ibsi;test_2d_ngldm_dcene_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",,agree,feature,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs mirp 2.6.0 shape/texture extraction on the four IBSI phantom slices (by_slice, no discretisation, ngldm_distance=1, ngldm_difference_level=0), recipe ngldm.ibsi_phantom_2d; agreement 2.9e-16 worst case, asserted at rel=1e-9 in test_2d_ngldm_mirp.h. The same quantities are pinned against the published IBSI consensus in test_2d_ngldm_ibsi.h at rel=1e-2, which is the 3-significant-figure precision those values are published to. gen_ngldm_mirp.py" +2D,ngldm,NGLDM_DCENE,vetted,mirp,ngldm.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_square12_graded,TEST_NYXUS.TEST_2D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,ibsi;mirp,test_2d_ngldm_dcene_ibsi;test_2d_ngldm_dcene_mirp;test_2d_ngldm_negative_greydepth_mirp,,,3,0,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 2.9e-16",test_2d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_2d_mirp_vetting_report.md,audit/ngldm_2d_golden_regen.md,,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_square12_graded: a 12x12 ROI at 36 levels over 100-208 with 14 of its 144 pixels exactly on a bin edge at 20 bins; the 5 at 181 are the ones a division by the bin width sends one bin low. by_slice=True, distance 1, difference level 0. Measured residual 2.1e-16 worst case over the family; asserted at rel=1e-9 in test_2d_ngldm_mirp.h. gen_ngldm_mirp.py re-verifies every pin." 2D,ngtdm,NGTDM_COARSENESS,vetted,mirp,ngtdm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_NGTDM_COARSENESS_IBSI;TEST_NYXUS.TEST_2D_NGTDM_COARSENESS_MIRP,,,audit,ibsi;mirp,test_2d_ngtdm_coarseness_ibsi;test_2d_ngtdm_coarseness_mirp,test_2d_ngtdm_coarseness_regression,test_2d_ngtdm_ibsi_mode_ignores_n_levels_mechanics,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 3.2e-16, with a PyRadiomics run corroborating mirp to 1.6e-16",test_2d_ngtdm_coarseness_ibsi;test_2d_ngtdm_coarseness_mirp,agree,row,audit/ngtdm_2d_mirp_vetting_report.md,audit/ngtdm_2d_golden_regen.md,matrix/ngtdm.md,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md" 2D,ngtdm,NGTDM_CONTRAST,vetted,mirp,ngtdm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_NGTDM_CONTRAST_IBSI;TEST_NYXUS.TEST_2D_NGTDM_CONTRAST_MIRP,,,audit,ibsi;mirp,test_2d_ngtdm_contrast_ibsi;test_2d_ngtdm_contrast_mirp,test_2d_ngtdm_contrast_regression,test_2d_ngtdm_ibsi_mode_ignores_n_levels_mechanics,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 3.2e-16, with a PyRadiomics run corroborating mirp to 1.6e-16",test_2d_ngtdm_contrast_ibsi;test_2d_ngtdm_contrast_mirp,agree,row,audit/ngtdm_2d_mirp_vetting_report.md,audit/ngtdm_2d_golden_regen.md,matrix/ngtdm.md,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md" 2D,ngtdm,NGTDM_BUSYNESS,vetted,mirp,ngtdm.ibsi_phantom_2d,abs=1e-9,agreed,ibsi_digital_phantom,TEST_NYXUS.TEST_2D_NGTDM_BUSYNESS_IBSI;TEST_NYXUS.TEST_2D_NGTDM_BUSYNESS_MIRP,,,audit,ibsi;mirp,test_2d_ngtdm_busyness_ibsi;test_2d_ngtdm_busyness_mirp,test_2d_ngtdm_busyness_regression,test_2d_ngtdm_ibsi_mode_ignores_n_levels_mechanics,2,1,"asserted against both oracles by design: IBSI fixes the definition at its published 3-significant-figure precision, mirp fixes the digits at 3.2e-16, with a PyRadiomics run corroborating mirp to 1.6e-16",test_2d_ngtdm_busyness_ibsi;test_2d_ngtdm_busyness_mirp,agree,row,audit/ngtdm_2d_mirp_vetting_report.md,audit/ngtdm_2d_golden_regen.md,matrix/ngtdm.md,"vetted vs mirp 2.6.0 feature extraction on the four IBSI phantom slices (by_slice=True, base_discretisation_method=none), recipe ngtdm.ibsi_phantom_2d; agreement 3.6e-15 absolute and 3.2e-16 relative worst case, asserted on each slice AND on the four-slice mean at SPEC 7's exact tier -- an ABSOLUTE 1e-9 band -- in test_2d_ngtdm_mirp.h. PyRadiomics 3.0.1 -- the oracle this row used to name, against a target_test file that never existed -- was run on the same fixture and recipe and agrees with mirp to 1.6e-16, so the claim is corroborated rather than dropped; only mirp's values are pinned, a second identical table being redundancy and not coverage. The same quantities are pinned against the published IBSI consensus in test_2d_ngtdm_ibsi.h at rel=1e-2, the 3-significant-figure precision those values are published to. Re-measured 2026-08-20: this row previously carried an EMPTY tolerance. Nyxus' default mode is a separate config and has its own regression row at recipe ngtdm.default_fbn100. gen_ngtdm_mirp.py re-verifies every pin in the header it feeds; tests/vetting/audit/ngtdm_2d_mirp_vetting_report.md" @@ -739,149 +761,181 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 3D,glcm,3GLCM_SUMVARIANCE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_sumvariance_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." 3D,gldm,3GLDM_DE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=4e-3,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. 3GLDM_DE is the exception at abs=4e-3: it is the family's only sum over logarithms and Nyxus takes it through fast_log10(), a float-precision approximation divided by a ten-digit LOG10_2, where PyRadiomics uses numpy.log2. Measured residual 1.7512e-3 absolute / 2.65e-4 relative (Nyxus 6.6031219389041276 against PyRadiomics 6.6048731874541904); the band is that doubled and rounded up to one significant figure. A documented fast path, banded rather than reported. Note the 2D twin's identical calc_DE() measures 1.3e-3 RELATIVE, five times wider, so this figure is this family's own and not carried across. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_DE,regression,,gldm3d.regression_ut_phantom,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band." -3D,gldm,3GLDM_DE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band." +3D,gldm,3GLDM_DE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band." 3D,gldm,3GLDM_DE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DNN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_DV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_GLN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_GLV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_HGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. Specific to this feature: the retired table pinned 3GLDM_LGLE at 0.26, byte-identical to the 3GLDM_SDE pin beside it, against a measured 0.00073572128237550161 - a factor of 353 - and test_3d_gldm_lgle_regression() asserted Feature3D::GLDM_SDE under the _lgle_ name, so the feature had no drift guard at all and 3GLDM_SDE had two. Both halves of one paste, in a file nothing ran." -3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE COMPILED DEFAULT, not a third configuration someone might choose: Environment::compile_feature_settings() (src/nyx/env_features.cpp) zero-fills every settings vector and then names a default for GLCM_OFFSET, GLCM_GREYDEPTH, GLCM_NUMANG and the FPIMG_* group and for nothing else, so GLDM_GREYDEPTH stays at the zero-fill and only --3gldm/greydepth=N moves it. Every run that does not pass that option computes this family here, and IBSI=true reaches the same code path by forcing greyInfo=0. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." 3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,,,in-tree,mirp,test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,2,1,,test_3d_gldzm_sde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,2,1,,test_3d_gldzm_sde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,2,1,,test_3d_gldzm_sde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp,test_3d_gldzm_lde_regression,,2,1,,test_3d_gldzm_lde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp,test_3d_gldzm_lde_regression,,2,1,,test_3d_gldzm_lde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp,test_3d_gldzm_lde_regression,,2,1,,test_3d_gldzm_lde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp,test_3d_gldzm_lglze_regression,,2,1,,test_3d_gldzm_lglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp,test_3d_gldzm_lglze_regression,,2,1,,test_3d_gldzm_lglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp,test_3d_gldzm_lglze_regression,,2,1,,test_3d_gldzm_lglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp,test_3d_gldzm_hglze_regression,,2,1,,test_3d_gldzm_hglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp,test_3d_gldzm_hglze_regression,,2,1,,test_3d_gldzm_hglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp,test_3d_gldzm_hglze_regression,,2,1,,test_3d_gldzm_hglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,2,1,,test_3d_gldzm_sdlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,2,1,,test_3d_gldzm_sdlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,2,1,,test_3d_gldzm_sdlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,2,1,,test_3d_gldzm_sdhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,2,1,,test_3d_gldzm_sdhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,2,1,,test_3d_gldzm_sdhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp,test_3d_gldzm_ldlgle_regression,,2,1,,test_3d_gldzm_ldlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp,test_3d_gldzm_ldlgle_regression,,2,1,,test_3d_gldzm_ldlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp,test_3d_gldzm_ldlgle_regression,,2,1,,test_3d_gldzm_ldlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp,test_3d_gldzm_ldhgle_regression,,2,1,,test_3d_gldzm_ldhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp,test_3d_gldzm_ldhgle_regression,,2,1,,test_3d_gldzm_ldhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp,test_3d_gldzm_ldhgle_regression,,2,1,,test_3d_gldzm_ldhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp,test_3d_gldzm_glnu_regression,,2,1,,test_3d_gldzm_glnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp,test_3d_gldzm_glnu_regression,,2,1,,test_3d_gldzm_glnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp,test_3d_gldzm_glnu_regression,,2,1,,test_3d_gldzm_glnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp,test_3d_gldzm_glnun_regression,,2,1,,test_3d_gldzm_glnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp,test_3d_gldzm_glnun_regression,,2,1,,test_3d_gldzm_glnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp,test_3d_gldzm_glnun_regression,,2,1,,test_3d_gldzm_glnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,,,in-tree,mirp,test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,2,1,,test_3d_gldzm_zdnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,2,1,,test_3d_gldzm_zdnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,2,1,,test_3d_gldzm_zdnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,2,1,,test_3d_gldzm_zdnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,2,1,,test_3d_gldzm_zdnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,2,1,,test_3d_gldzm_zdnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,,,in-tree,mirp,test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,2,1,,test_3d_gldzm_zp_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,2,1,,test_3d_gldzm_zp_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,2,1,,test_3d_gldzm_zp_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.mirp_compat_phantom,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_COMPAT_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_compat_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_RADIOMICS_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_radiomics_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp,test_3d_gldzm_glv_regression,,2,1,,test_3d_gldzm_glv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp,test_3d_gldzm_glv_regression,,2,1,,test_3d_gldzm_glv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp,test_3d_gldzm_glv_regression,,2,1,,test_3d_gldzm_glv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.mirp_compat_phantom,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_COMPAT_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_compat_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_RADIOMICS_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_radiomics_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,,,in-tree,mirp,test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,2,1,,test_3d_gldzm_zdv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,2,1,,test_3d_gldzm_zdv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,2,1,,test_3d_gldzm_zdv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,,,in-tree,mirp,test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,2,1,,test_3d_gldzm_zde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,2,1,,test_3d_gldzm_zde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,2,1,,test_3d_gldzm_zde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." 3D,ngldm,3NGLDM_DCP,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCP_REGRESSION,non-discriminating-agreement,,in-tree,,,test_3d_ngldm_dcp_regression,,0,1,"no oracle row: Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, so the agreement cannot fail",test_3d_ngldm_dcp_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would pin the same Nyxus run to a second literal and add no path or config coverage. This one carries no oracle row because Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, at both config points -- an agreement that cannot fail for the reasons an assertion should fail. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." 3D,ngldm,3NGLDM_GLM,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLM_REGRESSION,,,in-tree,,,test_3d_ngldm_glm_regression,,0,1,no counterpart in any tool (MIRP's NGLDM emits no gl_mean column),test_3d_ngldm_glm_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." 3D,ngldm,3NGLDM_DCM,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCM_REGRESSION,,,in-tree,,,test_3d_ngldm_dcm_regression,,0,1,no counterpart in any tool (MIRP's NGLDM emits no dc_mean column),test_3d_ngldm_dcm_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp,,,2,0,,test_3d_ngldm_lde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp,,,2,0,,test_3d_ngldm_hde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp,,,2,0,,test_3d_ngldm_lglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp,,,2,0,,test_3d_ngldm_hglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp,,,2,0,,test_3d_ngldm_ldlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp,,,2,0,,test_3d_ngldm_ldhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp,,,2,0,,test_3d_ngldm_hdlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp,,,2,0,,test_3d_ngldm_hdhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp,,,2,0,,test_3d_ngldm_glnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp,,,2,0,,test_3d_ngldm_glnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp,,,2,0,,test_3d_ngldm_dcnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp,,,2,0,,test_3d_ngldm_dcnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp,,,2,0,,test_3d_ngldm_glv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp,,,2,0,,test_3d_ngldm_dcv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp,,,2,0,,test_3d_ngldm_dcent_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp,,,2,0,,test_3d_ngldm_dcene_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp,,,2,0,,test_3d_ngldm_lde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp,,,2,0,,test_3d_ngldm_hde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp,,,2,0,,test_3d_ngldm_lglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp,,,2,0,,test_3d_ngldm_hglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp,,,2,0,,test_3d_ngldm_ldlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp,,,2,0,,test_3d_ngldm_ldhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp,,,2,0,,test_3d_ngldm_hdlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp,,,2,0,,test_3d_ngldm_hdhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp,,,2,0,,test_3d_ngldm_glnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp,,,2,0,,test_3d_ngldm_glnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp,,,2,0,,test_3d_ngldm_dcnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp,,,2,0,,test_3d_ngldm_dcnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp,,,2,0,,test_3d_ngldm_glv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp,,,2,0,,test_3d_ngldm_dcv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp,,,2,0,,test_3d_ngldm_dcent_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp,,,2,0,,test_3d_ngldm_dcene_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcent_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcene_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcent_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcene_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." 3D,ngtdm,3NGTDM_COARSENESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_COARSENESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_COARSENESS,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." @@ -897,93 +951,93 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 3D,ngtdm,3NGTDM_STRENGTH,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_STRENGTH,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_STRENGTH,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_gln_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_gln_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_gln_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_gln_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glnn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glnn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glnn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glnn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-3,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=2e-3,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." -3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." -3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_hglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_hglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_hglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_hglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lalgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lalgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lalgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lalgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_DEFAULT_GREYDEPTH_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_default_greydepth_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which is the value a run that passes no --3glszm/greydepth reaches the feature with. That makes this the family's default configuration rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers 0 here, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_gln_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glnn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_glv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_hglze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lalgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_default_greydepth_regression;test_3d_glszm_lahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-3,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=2e-3,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." +3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." +3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." 3D,glrlm,3GLRLM_SRE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_sre_pyradiomics,test_3d_glrlm_sre_grey64_regression;test_3d_glrlm_sre_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_LRE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_lre_pyradiomics,test_3d_glrlm_lre_grey64_regression;test_3d_glrlm_lre_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_GLN,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_gln_pyradiomics,test_3d_glrlm_gln_grey64_regression;test_3d_glrlm_gln_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_GLNN,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_glnn_pyradiomics,test_3d_glrlm_glnn_grey64_regression;test_3d_glrlm_glnn_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_RLN,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_rln_pyradiomics,test_3d_glrlm_rln_grey64_regression;test_3d_glrlm_rln_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_RLNN,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_rlnn_pyradiomics,test_3d_glrlm_rlnn_grey64_regression;test_3d_glrlm_rlnn_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." -3D,glrlm,3GLRLM_RP,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_rp_pyradiomics,test_3d_glrlm_rp_grey64_regression;test_3d_glrlm_rp_regression,,2,2,exceeds its mathematical bound of 1 at positive GLRLM_GREYDEPTH values; in range at the binCount binning both tests use,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." +3D,glrlm,3GLRLM_RP,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_rp_pyradiomics,test_3d_glrlm_rp_grey64_regression;test_3d_glrlm_rp_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_GLV,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_glv_pyradiomics,test_3d_glrlm_glv_grey64_regression;test_3d_glrlm_glv_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_RV,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_rv_pyradiomics,test_3d_glrlm_rv_grey64_regression;test_3d_glrlm_rv_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_RE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=2e-3,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_re_pyradiomics,test_3d_glrlm_re_grey64_regression;test_3d_glrlm_re_regression,,2,2,"the family's only sum over logarithms; fast_log10 puts it 3.9e-4 from PyRadiomics, so it is asserted at rel=5e-3 where the rest are at rel=1e-9",,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual 6.2e-4 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle. 3GLRLM_RE is the family's only sum over logarithms and Nyxus evaluates it through fast_log10 (helpers.h), a float-precision log2 approximation, against PyRadiomics' double numpy.log2 - that is the band, not a definitional difference." diff --git a/tests/vetting/report_output.md b/tests/vetting/report_output.md index 2b4e95775..d5868e637 100644 --- a/tests/vetting/report_output.md +++ b/tests/vetting/report_output.md @@ -32,11 +32,11 @@ regression: 121 invariant: 0 untested: 0 ## Verdicts -1020 of 1020 assertion rows agree with the tree. +1074 of 1074 assertion rows agree with the tree. | verdict | rows | meaning | |---|---:|---| -| `agree` | 1020 | the claim and the tree say the same thing | +| `agree` | 1074 | the claim and the tree say the same thing | ### How far each verdict reaches @@ -46,8 +46,8 @@ regression: 121 invariant: 0 untested: 0 | scope | rows | what was compared | |---|---:|---| | `feature` | 533 | `test_name` is empty, so the tree was read for the feature and not for this row's own assertion | -| `row` | 280 | the case named in `test_name` asserts this feature, at this row's kind; its configuration is unchecked, the family declaring no recipe reader | -| `row+config` | 207 | the case named in `test_name` asserts this feature at this `config_recipe` | +| `row` | 318 | the case named in `test_name` asserts this feature, at this row's kind; its configuration is unchecked, the family declaring no recipe reader | +| `row+config` | 223 | the case named in `test_name` asserts this feature at this `config_recipe` | ## Every oracle a feature was matched against From c42d6fae64a0a7a84d6b1095f7c9bab74eccd6cf Mon Sep 17 00:00:00 2001 From: Demian Vladi Date: Wed, 21 Oct 2026 07:15:11 -0700 Subject: [PATCH 2/3] fix(binning)!: bin a 3D ROI voxel at the volume minimum into level 1 Nyxus stores a volume offset by its lowest intensity, so a ROI that holds the volume minimum has voxels stored as 0, the value the background cells of its bounding box hold. to_grayscale_radiomix() keeps 0 at 0, so under PyRadiomics-style binning those ROI voxels went to level 0 instead of floor(n (x - min) / (max - min)) + 1 = 1. 3D GLCM, GLDM, GLRLM and GLSZM then read them as background and dropped them; 3D GLDZM lifted every level by one to make room for them; 3D NGLDM gave them level 0; 3D NGTDM lifted every level by one and so carried an extra grey level. On a CT whose ROI holds the volume minimum (140 of 10.5M voxels at -1024 HU) at binCount 20, 3NGTDM_BUSYNESS was 32% off PyRadiomics and 3NGTDM_CONTRAST 9.5%; GLRLM, GLDM and GLCM by up to 4.5e-4, 1.7e-4 and 4.5e-5. The fix fills each family's binned cube from the voxel cloud with one rule: Nyxus::roi_voxel_binning() / TextureFeature::bin_roi_voxel() bins a voxel known to be the ROI's, so PyRadiomics-style binning takes IBSI's fixed bin number with no special case for 0 and MATLAB-style binning its level 1..n. Every ROI voxel gets a level of 1 or more, so level 0 marks the cells that are not the ROI's again, and the families' existing zeroI / U.erase(0) tests read it as background without a mask of their own. - bin_roi_3d() (in RAM) and every OocBinnedVolume (out of core) bin through that rule, for 3D GLCM, GLDM, GLRLM, GLSZM, GLDZM and NGTDM; their out-of-core background is level 0 in every scheme. - 3D NGLDM keeps its own positive scheme and takes the same fixed bin number under PyRadiomics-style binning (ngldm_roi_grey_level()); 2D NGLDM still calls ngldm_grey_level(). - 3D GLCM builds its matrix from bin_roi_3d() and skips pairs with a level-0 cell under every scheme. Under MATLAB-style binning it had read the background as level 1 and paired it with the ROI, so its default output moves on every ROI that does not fill its bounding box, and on every whole-volume run, whose box is one voxel larger than the volume on each axis. This is the 3D GLCM part of the background-as-level-1 issue; 3D GLRLM, GLSZM and GLDM were already masked. - 3D GLDZM lifts its levels only with no binning, the one scheme that still hands it a ROI voxel at level 0. - 3D NGTDM bins through the same rule but still takes the whole bounding box as its levels and neighbourhoods; the ROI mask of 3D NGTDM comes from its own fix. Its background now sits at level 0, which its zero-lift moves to 1 together with every ROI level, so its default output moves on every ROI that does not fill its box (the five regression pins on the segmented phantom by 1.3-1.6%). Merged with the mask, PyRadiomics agrees to ~1e-15 on the CT above. Unchanged: with no binning (greydepth 0 / IBSI) a ROI voxel of raw stored value 0 is still indistinguishable from background and dropped by 3D GLCM, GLDM, GLRLM and GLSZM. 2D texture families still bin a stored 0 to 0 under PyRadiomics-style binning (measured: on a slice whose ROI holds the image minimum all seven 2D families move). Both stay open on the board. Tests, each failing on the previous commit: - bench_volmin_3d (tests/vetting/oracles/volmin_phantom.py): an int16 CT-like volume whose ellipsoid ROI holds the volume minimum and leaves background in its box; its control moves the minimum outside the box. 3D GLCM, GLDM, GLRLM and GLSZM against PyRadiomics 3.0.1 at binCount 8, 3D GLDZM and NGLDM against MIRP fixed_bin_number 8, rel 1e-9, on both phantoms, in RAM and out of core (24 cases; the 12 volmin cases fail before, the 12 control cases pass before and after). Logarithmic features keep the fast_log10 residual and are left out. - 3D GLCM at the default depth 64 against its co-occurrence definition (ASM, CONTRAST) on an ellipsoid with background in its box, in RAM and out of core; a ROI that fills its box is the negative case. - bin_roi_3d() puts a ROI voxel stored as 0 at level 1 under both binning schemes, keeps it at 0 with no binning, and leaves background at 0. - 3D GLDZM at bin count 5 on its zero-level fixture now expects levels 1 and 5, IBSI's fixed bin number; the previous expectation of 1 and 6 was the lift. - The 3D GLCM grey64 regression table is regenerated (background no longer pairs; a dump helper regenerates it), and the 3D NGTDM regression pins move with the background level. - The registry records the new recipes, the fixture and the rows. - The Nyxus3D docstring names 3D GLCM's matrix as what a large grey depth costs. BREAKING CHANGE: at the default grey depth (64, MATLAB-style binning) 3D GLCM no longer pairs the bounding box's background with the ROI, so its output changes on every ROI that does not fill its bounding box and on every whole-volume run. 3D NGTDM's default output changes on the same ROIs, whose grey levels it now lifts by one. Under PyRadiomics-style binning (negative depth) every 3D texture family changes on a ROI that holds the volume's lowest intensity, whose voxels there now take bin 1. --- src/nyx/features/3d_glcm.cpp | 24 +- src/nyx/features/3d_glcm_nontriv.cpp | 22 +- src/nyx/features/3d_gldm.cpp | 5 +- src/nyx/features/3d_gldzm.cpp | 27 +- src/nyx/features/3d_glrlm_nontriv.cpp | 2 +- src/nyx/features/3d_glszm.cpp | 3 +- src/nyx/features/3d_ngldm.cpp | 8 +- src/nyx/features/3d_ngtdm.cpp | 12 +- src/nyx/features/3d_ooc_volume.h | 24 +- src/nyx/features/texture_feature.h | 58 +- src/nyx/python/nyxus/nyxus.py | 12 +- .../data/nifti/phantoms/volmin_ctrl_inten.nii | Bin 0 -> 3488 bytes tests/data/nifti/phantoms/volmin_inten.nii | Bin 0 -> 3488 bytes tests/data/nifti/phantoms/volmin_mask.nii | Bin 0 -> 1920 bytes tests/python/test_3d_glcm_analytic.py | 104 +++ tests/python/test_3d_glcm_pyradiomics.py | 57 ++ tests/python/test_3d_gldm_pyradiomics.py | 52 ++ tests/python/test_3d_gldzm_mirp.py | 52 ++ tests/python/test_3d_glrlm_pyradiomics.py | 54 ++ tests/python/test_3d_glszm_pyradiomics.py | 54 ++ tests/python/test_3d_ngldm_mirp.py | 55 ++ .../test_3d_texture_background_mechanics.py | 4 +- tests/python/test_data.py | 61 ++ tests/test_3d_glcm_regression.h | 104 +-- tests/test_3d_gldm_pyradiomics.h | 6 +- tests/test_3d_gldzm_mechanics.h | 53 +- tests/test_3d_ngtdm_regression.h | 17 +- tests/test_all.cc | 5 + tests/test_texture_binning_mechanics.h | 34 +- tests/vetting/audit/glcm_3d_golden_regen.md | 9 +- .../gldm_3d_pyradiomics_vetting_report.md | 2 +- tests/vetting/audit/glrlm_3d_golden_regen.md | 2 +- tests/vetting/audit/glszm_3d_golden_regen.md | 2 +- .../glszm_3d_pyradiomics_vetting_report.md | 2 +- tests/vetting/audit/ngtdm_3d_golden_regen.md | 7 +- .../ngtdm_3d_pyradiomics_vetting_report.md | 10 +- tests/vetting/audit/scan_glcm3d_coverage.py | 59 +- tests/vetting/audit/scan_gldm3d_coverage.py | 28 +- tests/vetting/audit/scan_gldzm3d_coverage.py | 70 +- tests/vetting/audit/scan_glrlm3d_coverage.py | 5 + tests/vetting/audit/scan_glszm3d_coverage.py | 48 +- tests/vetting/audit/scan_ngldm3d_coverage.py | 64 +- tests/vetting/benchmarks.md | 67 ++ tests/vetting/config_recipes.md | 161 ++++- tests/vetting/matrix/gldm3d.md | 14 +- tests/vetting/matrix/gldzm3d.md | 6 +- tests/vetting/matrix/glszm3d.md | 3 +- tests/vetting/matrix/ngldm3d.md | 2 +- tests/vetting/matrix/ngtdm3d.md | 7 +- tests/vetting/oracle_coverage.csv | 321 ++++++--- .../vetting/oracles/gen_glcm3d_pyradiomics.py | 112 ++- .../vetting/oracles/gen_gldm3d_pyradiomics.py | 107 ++- tests/vetting/oracles/gen_gldzm3d_mirp.py | 91 ++- .../oracles/gen_glrlm3d_pyradiomics.py | 112 ++- .../oracles/gen_glszm3d_pyradiomics.py | 110 ++- tests/vetting/oracles/gen_ngldm3d_mirp.py | 114 ++- tests/vetting/oracles/volmin_phantom.py | 153 ++++ tests/vetting/report_output.csv | 655 ++++++++++-------- tests/vetting/report_output.md | 10 +- 59 files changed, 2625 insertions(+), 637 deletions(-) create mode 100644 tests/data/nifti/phantoms/volmin_ctrl_inten.nii create mode 100644 tests/data/nifti/phantoms/volmin_inten.nii create mode 100644 tests/data/nifti/phantoms/volmin_mask.nii create mode 100644 tests/python/test_3d_glcm_analytic.py create mode 100644 tests/python/test_3d_glcm_pyradiomics.py create mode 100644 tests/python/test_3d_gldm_pyradiomics.py create mode 100644 tests/python/test_3d_gldzm_mirp.py create mode 100644 tests/python/test_3d_glrlm_pyradiomics.py create mode 100644 tests/python/test_3d_glszm_pyradiomics.py create mode 100644 tests/python/test_3d_ngldm_mirp.py create mode 100644 tests/vetting/oracles/volmin_phantom.py diff --git a/src/nyx/features/3d_glcm.cpp b/src/nyx/features/3d_glcm.cpp index 19c6df942..25a6bfd7b 100644 --- a/src/nyx/features/3d_glcm.cpp +++ b/src/nyx/features/3d_glcm.cpp @@ -1,5 +1,6 @@ #include #include "3d_glcm.h" +#include "3d_ooc_volume.h" #include "../helpers/helpers.h" #include "../environment.h" @@ -40,19 +41,13 @@ void D3_GLCM_feature::calculate (LR& r, const Fsettings& s) // clear the feature values buffers clear_result_buffers(); - // grey-bin intensities - int w = r.aux_image_cube.width(), - h = r.aux_image_cube.height(), - d = r.aux_image_cube.depth(); - - SimpleCube D; - D.allocate (w,h,d); - auto greyBinningInfo = STNGS_GLCM_GREYDEPTH(s); // former Nyxus::theEnvironment.get_coarse_gray_depth() if (STNGS_IBSI(s)) // former Nyxus::theEnvironment.ibsi_compliance greyBinningInfo = 0; - bin_intensities_3d (D, r.aux_image_cube, r.aux_min, r.aux_max, greyBinningInfo); + // grey-bin the ROI's voxels; the background outside the ROI takes level 0, which pairs with nothing + SimpleCube D; + Nyxus::bin_roi_3d (D, r, greyBinningInfo); // calculate features for all the 13 directions for (const ShiftToNeighbor & sh : shifts) @@ -340,10 +335,9 @@ void D3_GLCM_feature::calculateCoocMatAtAngle( PixIntens lvl_b = D.zyx(zslice, row, col), lvl_a = D.zyx(zslice + dz, row + dy, col + dx); - // Skip 0-intensity pixels (usually out of mask pixels) - if (ibsi_grey_binning(greyInfo)) - if (lvl_a == 0 || lvl_b == 0) - continue; + // skip pairs with a background cell, which holds level 0 under every binning scheme + if (lvl_a == 0 || lvl_b == 0) + continue; // 0-based grey tone indices, hence '-1' int a = lvl_a, @@ -352,10 +346,6 @@ void D3_GLCM_feature::calculateCoocMatAtAngle( // raw intensities need to be modified for different grey binning paradigms (Matlab, PyRadiomics, IBSI) if (radiomics_grey_binning(greyInfo)) { - // skip zeroes - if (a == 0 || b == 0) - continue; - // index of 'a' auto lower = std::lower_bound(I.begin(), I.end(), a); // enjoy sorted vector 'I' a = int(lower - I.begin()); // intensity index in array of unique intensities 'I' diff --git a/src/nyx/features/3d_glcm_nontriv.cpp b/src/nyx/features/3d_glcm_nontriv.cpp index 7f444b4fb..263746395 100644 --- a/src/nyx/features/3d_glcm_nontriv.cpp +++ b/src/nyx/features/3d_glcm_nontriv.cpp @@ -29,18 +29,14 @@ void D3_GLCM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader&) int greyInfo = STNGS_IBSI(s) ? 0 : STNGS_GLCM_GREYDEPTH(s); bool ibsi = STNGS_IBSI(s); double soft_nan = STNGS_NAN(s); - PixIntens mn = r.aux_min, mx = r.aux_max; - - // background cells carry the binned level of intensity 0, as they do in the in-core cube - const PixIntens bg = TextureFeature::bin_pixel (0, mn, mx, greyInfo); - Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, - bg, D3_GLCM_feature::offset + 1); + // as in calculate(), background cells carry level 0 and every ROI voxel 1 or more + Nyxus::OocBinnedVolume vol (r, Nyxus::roi_voxel_binning (r, greyInfo), 0, D3_GLCM_feature::offset + 1); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); - // --- the grey levels I. Under radiomics binning they are the unique levels of the whole binned - // cube, so the background level counts when the bounding box has background. + // --- the grey levels I. Under radiomics binning they are the unique nonzero levels of the ROI's + // voxels. PixIntens maxbin = 0; - std::set uniq = vol.levels (/*with_background=*/ true, /*drop_zero=*/ true, maxbin); + std::set uniq = vol.levels (/*with_background=*/ false, /*drop_zero=*/ true, maxbin); I.clear(); if (radiomics_grey_binning(greyInfo)) @@ -93,14 +89,12 @@ void D3_GLCM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader&) // symmetric: radiomics, no binning, or symmetric_glcm auto add_pair = [&](SimpleMatrix& M, PixIntens lvl_base, PixIntens lvl_nbr) { - if (ibsi_grey_binning(greyInfo)) - if (lvl_nbr == 0 || lvl_base == 0) - return; + // a background cell holds level 0 under every binning scheme + if (lvl_nbr == 0 || lvl_base == 0) + return; int a = (int) lvl_nbr, b = (int) lvl_base; if (radiomics) { - if (a == 0 || b == 0) - return; a = rowLUT[a]; b = rowLUT[b]; } diff --git a/src/nyx/features/3d_gldm.cpp b/src/nyx/features/3d_gldm.cpp index 809e5716e..3338bbd76 100644 --- a/src/nyx/features/3d_gldm.cpp +++ b/src/nyx/features/3d_gldm.cpp @@ -254,10 +254,9 @@ void D3_GLDM_feature::osized_calculate(LR& r, const Fsettings& s, ImageLoader&) } int greyInfo = STNGS_IBSI(s) ? 0 : STNGS_GLDM_GREYDEPTH(s); - PixIntens mn = r.aux_min, mx = r.aux_max; - // as in calculate(), the background outside the ROI takes level 0 - Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, 0, 3); + // as in calculate(), the background outside the ROI takes level 0 and every ROI voxel 1 or more + Nyxus::OocBinnedVolume vol (r, Nyxus::roi_voxel_binning (r, greyInfo), 0, 3); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); // --- grey levels I: the unique nonzero levels of the binned cube, which are the ROI's own diff --git a/src/nyx/features/3d_gldzm.cpp b/src/nyx/features/3d_gldzm.cpp index b42b341f7..e612026cd 100644 --- a/src/nyx/features/3d_gldzm.cpp +++ b/src/nyx/features/3d_gldzm.cpp @@ -151,10 +151,6 @@ void D3_GLDZM_feature::prepare_GLDZM_matrix_kit (SimpleMatrix& GLD // -- Zones (intensity clusters) std::vector Z; - // -- binned intensities - SimpleCube D; - D.allocate (r.aux_image_cube.width(), r.aux_image_cube.height(), r.aux_image_cube.depth()); - auto greyInfo = STNGS_NGREYS(s); // former Nyxus::theEnvironment.get_coarse_gray_depth() auto greyInfo_localFeature = D3_GLDZM_feature::n_levels; if (greyInfo_localFeature != 0 && greyInfo != greyInfo_localFeature) @@ -162,14 +158,14 @@ void D3_GLDZM_feature::prepare_GLDZM_matrix_kit (SimpleMatrix& GLD if (STNGS_IBSI(s)) // former Nyxus::theEnvironment.ibsi_compliance greyInfo = 0; - auto& imR = r.aux_image_cube; - bin_intensities_3d (D, imR, r.aux_min, r.aux_max, greyInfo); + // -- binned intensities of the ROI's voxels, background at 0 + SimpleCube D; + Nyxus::bin_roi_3d (D, r, greyInfo); // -- which voxels are the ROI's, marked in the cube that will go on to hold their distance to its - // border. The binned cube cannot answer this: matlab binning sends intensity 0 to level 1, so - // after binning the background filling the rest of the bounding box is indistinguishable from a - // genuine level-1 ROI voxel. The voxel cloud is what knows, and the 2D twin ngldm.cpp masks from - // it for the same reason. + // border. The binned cube cannot answer this: with no binning a ROI voxel of raw intensity 0 holds + // level 0, the background's level. The voxel cloud is what knows, and the 2D twin ngldm.cpp masks + // from it for the same reason. // allocate() value-initialises a fresh cube, so every voxel starts at 0, "not the ROI's". SimpleCube dist; dist.allocate (D.width(), D.height(), D.depth()); @@ -177,10 +173,10 @@ void D3_GLDZM_feature::prepare_GLDZM_matrix_kit (SimpleMatrix& GLD ymin = r.aabb.get_ymin(), zmin = r.aabb.get_zmin(); - // -- a GLDZM grey level is 1-based, and two of the three binning schemes can hand back a 0 for a + // -- a GLDZM grey level is 1-based, and one of the three binning schemes can hand back a 0 for a // voxel that is genuinely the ROI's: the IBSI setting bins nothing at all, so a raw intensity of 0 - // stays 0, and the radiomics scheme maps 0 to 0 by construction. Only the MATLAB scheme, which - // sends 0 to level 1, cannot. Lifting the ROI's levels by one where that happens is what keeps + // stays 0. The radiomics and MATLAB schemes give every ROI voxel a level of 1 or more + // (Nyxus::roi_voxel_binning), so they never lift. Lifting the ROI's levels by one where it happens is what keeps // those voxels in a zone; dropping them instead would take them out of Ns, out of the zone map and // out of the ZP denominator's numerator while they still counted in the ROI's voxel total. // The lift is by one, not a re-map onto a dense ladder: it makes the levels valid and changes @@ -576,10 +572,9 @@ void D3_GLDZM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& if (STNGS_IBSI(s)) greyInfo = 0; - const PixIntens mn = r.aux_min, mx = r.aux_max; const bool ibsi_levels = ibsi_grey_binning (greyInfo); - auto bin_of = [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }; + auto bin_of = Nyxus::roi_voxel_binning (r, greyInfo); // the ROI's binned cube, streamed, with its mask: a cell holding the fill level is otherwise // indistinguishable from a ROI voxel that binned to it @@ -597,7 +592,7 @@ void D3_GLDZM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& }; // --- one streaming pass marks the ROI and gathers its grey levels. A GLDZM grey level is - // 1-based, and the IBSI and radiomics schemes can bin a ROI voxel to 0, so the levels are lifted + // 1-based, and with no binning a ROI voxel of raw intensity 0 has level 0, so the levels are lifted // by one when any ROI voxel has level 0. Whether to lift is only known once the pass is over. std::vector dist ((size_t) W * H * Dz, 0); bool roi_has_zero_level = false; diff --git a/src/nyx/features/3d_glrlm_nontriv.cpp b/src/nyx/features/3d_glrlm_nontriv.cpp index b77d76f63..d593a5799 100644 --- a/src/nyx/features/3d_glrlm_nontriv.cpp +++ b/src/nyx/features/3d_glrlm_nontriv.cpp @@ -46,7 +46,7 @@ void D3_GLRLM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& // the ROI's binned cube, streamed: a cross-plane run reaches one plane back, so the window // keeps 2 planes. As in calculate(), the background outside the ROI takes level 0, at which no // run is counted. - Nyxus::OocBinnedVolume vol (r, [minI, maxI, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, minI, maxI, greyInfo); }, 0, 2); + Nyxus::OocBinnedVolume vol (r, Nyxus::roi_voxel_binning (r, greyInfo), 0, 2); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); const size_t nvox = vol.n_voxels(); diff --git a/src/nyx/features/3d_glszm.cpp b/src/nyx/features/3d_glszm.cpp index 7a8c68fa4..32fc4f13c 100644 --- a/src/nyx/features/3d_glszm.cpp +++ b/src/nyx/features/3d_glszm.cpp @@ -55,12 +55,11 @@ void D3_GLSZM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& int greyInfo = STNGS_GLSZM_GREYDEPTH(s); if (STNGS_IBSI(s)) greyInfo = 0; - PixIntens mn = r.aux_min, mx = r.aux_max; // the ROI's binned cube, streamed: the connected-component pass below reaches one plane back, // so the window keeps 2 planes. As in calculate(), the background outside the ROI takes level 0, // which grows no zone and is no grey level. - Nyxus::OocBinnedVolume vol (r, [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }, 0, 2); + Nyxus::OocBinnedVolume vol (r, Nyxus::roi_voxel_binning (r, greyInfo), 0, 2); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); // --- grey levels I. The construction follows the binning mode, ibsi_grey_binning(); the row diff --git a/src/nyx/features/3d_ngldm.cpp b/src/nyx/features/3d_ngldm.cpp index bf26daefd..27c3c4e1b 100644 --- a/src/nyx/features/3d_ngldm.cpp +++ b/src/nyx/features/3d_ngldm.cpp @@ -114,7 +114,7 @@ void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& PixIntens cpi = I.zyx (z, y, x); // Binned intensity - PixIntens cpi_ = TextureFeature::ngldm_grey_level (cpi, min_inten, max_inten, nGrays, ibsi); // binned 'cpi' + PixIntens cpi_ = TextureFeature::ngldm_roi_grey_level (cpi, min_inten, max_inten, nGrays, ibsi); // binned 'cpi' // Get a dense index value for sparse binned intensity cpi_ auto iter = std::find(U.begin(), U.end(), cpi_); @@ -133,7 +133,7 @@ void D3_NGLDM_feature::calc_ngld_matrix (SimpleMatrix& NGLDM, int& continue; PixIntens npi = I.zyx (nz, ny, nx); // neighboring voxel intensity - PixIntens npi_ = TextureFeature::ngldm_grey_level (npi, min_inten, max_inten, nGrays, ibsi); // binned 'npi' + PixIntens npi_ = TextureFeature::ngldm_roi_grey_level (npi, min_inten, max_inten, nGrays, ibsi); // binned 'npi' if (cpi_ == npi_) n_matches++; } @@ -211,7 +211,7 @@ void D3_NGLDM_feature::prepare_NGLDM_matrix_kit (SimpleMatrix& NGL for (const auto& p : r.raw_pixels_3D) { roi_mask.zyx (p.z - zmin, p.y - ymin, p.x - xmin) = 1; - U.insert (TextureFeature::ngldm_grey_level (p.inten, r.aux_min, r.aux_max, n_greys, ibsi)); + U.insert (TextureFeature::ngldm_roi_grey_level (p.inten, r.aux_min, r.aux_max, n_greys, ibsi)); } // Cast the set to vector to be able to access intensities by indices @@ -416,7 +416,7 @@ void D3_NGLDM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& // a cell holding the fill level is otherwise indistinguishable from a ROI voxel that binned to it const PixIntens bg = TextureFeature::ngldm_grey_level (0, mn, mx, nGrays, ibsi); - Nyxus::OocBinnedVolume vol (r, [mn, mx, nGrays, ibsi](PixIntens v) { return TextureFeature::ngldm_grey_level (v, mn, mx, nGrays, ibsi); }, + Nyxus::OocBinnedVolume vol (r, [mn, mx, nGrays, ibsi](PixIntens v) { return TextureFeature::ngldm_roi_grey_level (v, mn, mx, nGrays, ibsi); }, bg, 3, /*with_mask=*/ true); const int W = vol.width(), H = vol.height(), Dz = vol.depth(); diff --git a/src/nyx/features/3d_ngtdm.cpp b/src/nyx/features/3d_ngtdm.cpp index 78162e5f4..782b120f9 100644 --- a/src/nyx/features/3d_ngtdm.cpp +++ b/src/nyx/features/3d_ngtdm.cpp @@ -190,14 +190,13 @@ void D3_NGTDM_feature::calculate (LR& r, const Fsettings& s) h = r.aux_image_cube.height(), d = r.aux_image_cube.depth(); - SimpleCube D; - D.allocate(w, h, d); - auto greyInfo = STNGS_NGTDM_GREYDEPTH(s); if (STNGS_IBSI(s)) greyInfo = 0; - bin_intensities_3d (D, r.aux_image_cube, r.aux_min, r.aux_max, greyInfo); + // the ROI's voxels at their grey levels, the rest of the bounding box at 0 + SimpleCube D; + Nyxus::bin_roi_3d (D, r, greyInfo); // unique intensities (set) std::unordered_set U (D.begin(), D.end()); @@ -283,10 +282,9 @@ void D3_NGTDM_feature::osized_calculate (LR& r, const Fsettings& s, ImageLoader& int greyInfo = STNGS_IBSI(s) ? 0 : STNGS_NGTDM_GREYDEPTH(s); bool ibsi = STNGS_IBSI(s); - PixIntens mn = r.aux_min, mx = r.aux_max; - const PixIntens bg = TextureFeature::bin_pixel (0, mn, mx, greyInfo); + const PixIntens bg = 0; // as in calculate(), the rest of the bounding box is at level 0 - auto bin_of = [mn, mx, greyInfo](PixIntens v) { return TextureFeature::bin_pixel (v, mn, mx, greyInfo); }; + auto bin_of = Nyxus::roi_voxel_binning (r, greyInfo); // --- unique binned levels over the whole cube (mask + background if the bbox has any) Nyxus::OocBinnedVolume scan (r, bin_of, bg, 1); diff --git a/src/nyx/features/3d_ooc_volume.h b/src/nyx/features/3d_ooc_volume.h index ee63c5502..3e7c2704b 100644 --- a/src/nyx/features/3d_ooc_volume.h +++ b/src/nyx/features/3d_ooc_volume.h @@ -169,12 +169,25 @@ namespace Nyxus return lut; } + /// @brief The grey level of each of the ROI's voxels under 'greybin_info', as every 3D texture + /// family that bins the ROI over [aux_min, aux_max] takes it, in RAM (bin_roi_3d) and out of core + /// (the functor an OocBinnedVolume is built with): TextureFeature::bin_roi_voxel(), which gives + /// every ROI voxel a level of 1 or more under both binning schemes. + inline auto roi_voxel_binning (const LR& r, int greybin_info) + { + const PixIntens mn = r.aux_min, mx = r.aux_max; + return [mn, mx, greybin_info](PixIntens v) { return TextureFeature::bin_roi_voxel (v, mn, mx, greybin_info); }; + } + /// @brief The in-core counterpart of OocBinnedVolume: the ROI's bounding-box cube with every ROI /// voxel at its grey level under 'greybin_info' and every other cell at level 0, the level the - /// texture families read as background. It is written from the voxel cloud because a binned value - /// cannot mark the background: MATLAB binning sends intensity 0 to level 1, where the ROI's darkest - /// voxels land too. The cube is sized from r.aabb, the box every voxel is checked against, so a - /// voxel that passes the check has a cell. + /// texture families read as background. It is written from the voxel cloud because neither the raw + /// nor the binned value of a cell can mark the background: a ROI voxel at the image's lowest + /// intensity is stored as 0, and MATLAB binning sends intensity 0 to level 1, where the ROI's + /// darkest voxels land too. roi_voxel_binning() gives every ROI voxel a level of 1 or more under + /// both binning schemes, so level 0 means background there; with no binning a ROI voxel of + /// intensity 0 keeps level 0. The cube is sized from r.aabb, the box every voxel is checked + /// against, so a voxel that passes the check has a cell. inline void bin_roi_3d (SimpleCube& D, const LR& r, int greybin_info) { D.allocate ((int) r.aabb.get_width(), (int) r.aabb.get_height(), (int) r.aabb.get_z_depth()); @@ -182,10 +195,11 @@ namespace Nyxus const auto xmin = r.aabb.get_xmin(), ymin = r.aabb.get_ymin(), zmin = r.aabb.get_zmin(); + const auto bin = roi_voxel_binning (r, greybin_info); for (const auto& p : r.raw_pixels_3D) { r.aabb.require_contains (p.x, p.y, p.z); - D.zyx (p.z - zmin, p.y - ymin, p.x - xmin) = TextureFeature::bin_pixel (p.inten, r.aux_min, r.aux_max, greybin_info); + D.zyx (p.z - zmin, p.y - ymin, p.x - xmin) = bin (p.inten); } } } diff --git a/src/nyx/features/texture_feature.h b/src/nyx/features/texture_feature.h index eec6c83af..5a2ba9421 100644 --- a/src/nyx/features/texture_feature.h +++ b/src/nyx/features/texture_feature.h @@ -99,6 +99,21 @@ class TextureFeature } } + // The grey level of a ROI voxel of intensity 'x', the ROI spanning [min_I_inten, max_I_inten], under + // 'greybin_info'. Unlike bin_pixel(), it is never handed a background cell, so it has no use for + // intensity 0 as a background marker: PyRadiomics-style binning puts every ROI voxel, one at + // intensity 0 included, in bin 1..n, and MATLAB-style binning in level 1..n. Level 0 is therefore + // free to mark the cells of a bounding box that are not the ROI's. With no binning the level is + // the raw intensity, so a ROI voxel of intensity 0 keeps level 0 there. + static PixIntens bin_roi_voxel (PixIntens x, PixIntens min_I_inten, PixIntens max_I_inten, int greybin_info) + { + if (radiomics_grey_binning(greybin_info)) + return fixed_bin_number (x, min_I_inten, max_I_inten, std::abs(greybin_info)); + if (matlab_grey_binning(greybin_info)) + return bin_pixel_matlab (x, max_I_inten, greybin_info); + return x; + } + // NGLDM's grey level of intensity 'x' of a ROI spanning [min_I_inten, max_I_inten]. The sign of // 'greybin_info' selects the kind of scheme as it does for bin_pixel(), 0 keeping the raw level and // a negative value taking abs() PyRadiomics bins over [min, max]; IBSI keeps the raw level. A @@ -113,27 +128,40 @@ class TextureFeature return Nyxus::to_grayscale (x, 0, max_I_inten, greybin_info); } + // ngldm_grey_level() of a voxel known to be the ROI's, which 3D NGLDM reads off the voxel cloud: + // PyRadiomics-style binning puts it in bin 1..n as bin_roi_voxel() does, intensity 0 included. + // NGLDM's own positive scheme and the raw levels are ngldm_grey_level()'s. + static PixIntens ngldm_roi_grey_level (PixIntens x, PixIntens min_I_inten, PixIntens max_I_inten, int greybin_info, bool ibsi) + { + if (! ibsi && radiomics_grey_binning(greybin_info)) + return fixed_bin_number (x, min_I_inten, max_I_inten, std::abs(greybin_info)); + return ngldm_grey_level (x, min_I_inten, max_I_inten, greybin_info, ibsi); + } + static inline bool matlab_grey_binning (int greybinning_info) { return greybinning_info > 0; } static inline bool radiomics_grey_binning (int greybinning_info) { return greybinning_info < 0; } static inline bool ibsi_grey_binning (int greybinning_info) { return greybinning_info == 0; } - // returns 1-based bin indices: IBSI's fixed bin number, floor(n (x - min) / (max - min)) + 1. The - // product is taken before the division so that a level on a bin edge -- n (x - min) a multiple of - // (max - min), exact in double for integer levels -- lands in the bin above it, as it does in - // PyRadiomics and MIRP. A ROI of one intensity has a range of zero width, which is one bin. + // IBSI's fixed bin number of a level 'x' in [min__, max__]: floor(n (x - min) / (max - min)) + 1, + // 1-based. The product is taken before the division so that a level on a bin edge -- n (x - min) a + // multiple of (max - min), exact in double for integer levels -- lands in the bin above it, as it + // does in PyRadiomics and MIRP. A ROI of one intensity has a range of zero width, which is one bin. + static inline PixIntens fixed_bin_number (PixIntens x, PixIntens min__, PixIntens max__, int binCount) + { + if (max__ <= min__) + return 1; + PixIntens y = (PixIntens) (std::floor (double(binCount) * double(x - min__) / double(max__ - min__)) + 1); + if (y > binCount) + y = binCount; // the last bin is +1 unit wider + return y; + } + + // fixed_bin_number() of a cell of a matrix whose background is intensity 0, which stays 0. A ROI + // pixel of intensity 0 is indistinguishable from that background here and stays 0 too; the 3D + // families bin their ROI voxels through bin_roi_voxel() instead. static inline PixIntens to_grayscale_radiomix (PixIntens x, PixIntens min__, PixIntens max__, int binCount) { - if (x) - { - if (max__ <= min__) - return 1; - PixIntens y = (PixIntens) (std::floor (double(binCount) * double(x - min__) / double(max__ - min__)) + 1); - if (y > binCount) - y = binCount; // the last bin is +1 unit wider - return y; - } - else - return 0; + return x ? fixed_bin_number (x, min__, max__, binCount) : 0; } // 'afv' is angled feature values diff --git a/src/nyx/python/nyxus/nyxus.py b/src/nyx/python/nyxus/nyxus.py index f4e195114..b1505a806 100644 --- a/src/nyx/python/nyxus/nyxus.py +++ b/src/nyx/python/nyxus/nyxus.py @@ -1023,12 +1023,12 @@ class Nyxus3D: coarse_gray_depth: int (optional, default 64) Grey binning of the texture features, selected by the sign: a positive value bins into that many MATLAB-style levels, 0 bins nothing (the raw levels, as IBSI reads them), and a - negative value bins into abs(value) PyRadiomics-style bins over each ROI's range. Every 2D - and 3D texture family uses it unless a family's own metaparameter overrides it. The - first-order histogram statistics use abs(value) bins, or 24 at 0. Any 32-bit integer but - -2**31 is accepted, but the magnitude sizes per-ROI buffers and output columns (HISTOGRAM - writes one column per bin, 2D GLCM allocates abs(value)**2 cells), so a depth beyond the - image's dynamic range adds no information and a very large one exhausts memory. + negative value bins into abs(value) PyRadiomics-style bins over each ROI's range. Every 3D + texture family uses it unless a family's own metaparameter overrides it. The first-order + histogram statistics use abs(value) bins, or 24 at 0. Any 32-bit integer but -2**31 is + accepted, but the magnitude sizes per-ROI buffers (3D GLCM allocates abs(value)**2 cells + per direction), so a depth beyond the volume's dynamic range adds no information and a + very large one exhausts memory. n_feature_calc_threads: int (optional, default 4) Number of threads to use for feature calculation parallelization purposes. use_gpu_device: int (optional, default -1) diff --git a/tests/data/nifti/phantoms/volmin_ctrl_inten.nii b/tests/data/nifti/phantoms/volmin_ctrl_inten.nii new file mode 100644 index 0000000000000000000000000000000000000000..83606c8e578ac395d34cee5895cb4181011932ff GIT binary patch literal 3488 zcmbtX$!^p@5N!kpP6%mEbITngf%yOq$fx-QWC_WUKw=UE2@VHKe1cE&4eY}j2s;S` zLx8X^NB;#HbxFK(O}X2inJ5xtMaoon*Ye)0YR}0%W>=rR<^Z1kX3zL(9@=LP)`rW+ zjhXd#`$WBMhkq6>tt?-dJC@8X&95vipP!$*xOjHCKYzG?X5mbKxj%RA^r?lV#r_T+ zcDuAw@mxduvs;@n3x|$YhmZWdO4sN*-JqLvi-vTY?$BMjNB8N$O#3Q5oVuUwk7#Ye zkJ=y8lZJoa{*<28aohIi^rFf~?J*h4``P}IUXj|_e`qtS_I28*@?pEbpY5;d4b8G| z(%Y%~*b7+w(kbXaAcpa7=&IE{+ShjD`hbkXo z(r18?{xoKI(!Ncft9*n>@x%Ms{)N8oTDvK5VXdo%v}YWaVXaZ_rPUT<#yagP8Yz{i zGDeMIg(&-vfyn^hQ|iw97Nb-a6W;b!m4(2 z)HTFv3eE@MForsuc4MrTh?ig`M@531F#MKsWSD~C7%PgX&p?XG)c%#eRlPLHz&H9% zKWgoY7Ja0jkEhcr;$_IxAkUzl2C`pNX^?9dnTDQrOVpbKtpQdd{`)o7nU6P#KfP*-pk~aOn4r%R%Grr^o;7=-1YlQZxEfkGNqJPnd)5GhNsB_8XExZ1eJ!B zc6Fj;h!cS^?H$o>0fw|=6#KytHgU5-3$=Cv(OL}w#?v$_YgH`tH= zp6cHICJ~jJb<(cd)!uLn{NFo6+mF6WaK-wr!i@3l?rTf5D>owFCq6=|U4Or7)b}sU aDAGG?*Y_{XI7Hii{9gnbx5MLx^w1$+1JlOa|GXEb71^U9y(->)`lCW zjG6WC!RdP29{*Xmer@T>+{t8aasJxk(&hQNs~0aU_2-ZG&o7+sFZJgxojbd*c(K2S zhy53(w7Tu;hbeHbYeHzjOdPtAxF+HKDGwsXttaU%zpVP{e zAGN=rmlOVd`zpPv<2LQD=}nc7+G8@7_p|*iy(6`=|IlVu?Q67N<->M=Kil8a2byKy zppUKl*WU_dIHX2w-K$(XZq#mZzrT|2Z9uqmt} zAq>Zq*bY_;n^I68CruA zJ$M*cMtWn+K!D#3{AD;bvWXSsgvlPfjliBk%%MfDK>G8T;Wb!#I1?aNV%h$MzE=4N zlRg8C^!G8t)AmjJQRO2{iXYz3_Mf!1Z|$bQg|)64(w=cxhP6hymzEod8SAvGXrxr4 z${00<6{74v1||dio>HgAK(t%Ho?yjbEy8LEjx(HR?WQw6(eBWe;2^>tgYyae6jrsH zqpl%VQ*b^2hcVRQv>Ri!M7#tmIVuw5gyD~rBf}I7$5>HBeFjogruHq`u6k*jfo=Ll zziaJ^7JZ~&kEhcz;$_IxAkUzl2C`pNX^?9dnTDQrOVpbKtpQdd{`)o7nU6P#KbpYF+26P8(NOr=EYpn5sE~GPa;-2lsga{JZeb zsnHYdcCZ!zPk$P+c16=}UI~A{=@0FI0YSQleDq`cF8%eUkk7zh;yYSy)+Ph~+?5-S zr!~)Mor^l}WpYX;Jdar`GIuBRjOyLo_4`Y25S_a+rIc5h>Rj2nr^x~u8vyMDm4=me zb)sa56M-@99no$9hO}c9Th(qGe~c*S^9}t~fVBV}A=(#2Rnva|3DP&~dC&f1=tJ%N z8sc7>W==Oc>@{#^+Bembfu6@jqX?&HkIzu0LH_)2v;&S=$kvjr6_h9?;%szEj=n zZyHg#S*Pu)UF{9W!2i7&ntt>x!4>OUg&E`9-Pe|AS8hbUPke+_yZ(OFsPA8xQKa|Q VuJ2!%aWDU-AO9}`jobE@!atdM7K#7> literal 0 HcmV?d00001 diff --git a/tests/data/nifti/phantoms/volmin_mask.nii b/tests/data/nifti/phantoms/volmin_mask.nii new file mode 100644 index 0000000000000000000000000000000000000000..31578531867bf280c6b1b0b2e3b15cc4b4583ce5 GIT binary patch literal 1920 zcmd6lO%8%E5QPWbxbh6_jSJ%eTzCyPCXz^E!6-Gj^GF_1XgieG1}p><+mP~2=jYA9 zA)=r)r)9Ml6q$`dv+9P|Ye&@ey!Y(YcV^F0-s9~lE|Rj4w8 ztjI-Qiom1~ORvR~XVvayO(!`|(rHj-uAsSfRG(=EgkT!H?S+x~%f=&kQ z4P>FdL~5bUU%My`?5lu74OB;4nYH?FI*qYIP6n09g0FMzozq`~AjVhhTeJWObB6T) xJ>VA$?5G*p*Z$Dcp$1`ucFty))-d9&yCbJM|4q6^IGHpfr2QlWXNELw!4JFs8y)}v literal 0 HcmV?d00001 diff --git a/tests/python/test_3d_glcm_analytic.py b/tests/python/test_3d_glcm_analytic.py new file mode 100644 index 000000000..bf212c860 --- /dev/null +++ b/tests/python/test_3d_glcm_analytic.py @@ -0,0 +1,104 @@ +"""3D GLCM under MATLAB-style binning against the co-occurrence matrix built from its definition, on a +ROI that leaves background inside its bounding box, in RAM and out of core. + +MATLAB-style binning -- a positive grey depth, 64 by default -- sends intensity 0 to level 1, the level +the ROI's darkest voxels take too, so the binned value of a bounding-box cell cannot say whether it is +the ROI's. 3D GLCM takes the ROI from its voxel cloud: background cells hold level 0 and pair with +nothing. The reference below counts, for each of the 13 offsets at distance 1, the ordered pairs of ROI +voxels by their MATLAB levels, floor(64 x / max + 1) clipped to 1..64 over the ROI's maximum, and takes +ASM (sum p^2) and CONTRAST (sum (i - j)^2 p) of each normalised matrix, averaged over the 13 offsets. +Both are invariant under transposition, so the order in which a pair is counted does not matter, and +MATLAB-style binning keeps the matrix asymmetric on both sides. + +What this discriminates: a family that reads the bounding box's background as level 1 counts every +ROI-background pair and parts from the reference on the ellipsoid. The ROI that fills its bounding box +is the negative case: it has no background to count, so it holds either way. + +Kind: *analytic* per tests/vetting/SPEC.md 4: the reference is the definition evaluated by numpy. +""" +import numpy as np +import pytest + +import nyxus + +tifffile = pytest.importorskip("tifffile") + +RAM_LIMIT_LARGE_MB = 1000 # the in-RAM side, as in test_ooc_mechanics.py +RAM_LIMIT_OOC_MB = 0 # every ROI footprint is >= 0, so every ROI streams out of core +DEPTH = 64 # the default coarse grey depth, which the run leaves unset + +Z, Y, X = 6, 40, 40 + +# the 13 offsets of one hemisphere of the 26-neighbourhood, (dz, dy, dx) +OFFSETS = [(dz, dy, dx) for dz in (-1, 0, 1) for dy in (-1, 0, 1) for dx in (-1, 0, 1) + if (dz, dy, dx) > (0, 0, 0)] + + +def _volume(): + """Intensities 1..200 over the whole volume, none of them 0.""" + z, y, x = np.indices((Z, Y, X)) + return (1 + (x * 7 + y * 13 + z * 29) % 200).astype(np.uint32) + + +def _ellipsoid(): + z, y, x = np.indices((Z, Y, X)) + return ((((z - (Z - 1) / 2) / (Z / 2)) ** 2 + ((y - (Y - 1) / 2) / (Y / 3)) ** 2 + + ((x - (X - 1) / 2) / (X / 3)) ** 2) <= 1.0).astype(np.uint32) + + +def _box(): + mask = np.zeros((Z, Y, X), np.uint32) + mask[1:-1, 1:-1, 1:-1] = 1 + return mask + + +def _reference(inten, mask): + """-> {"3GLCM_ASM_AVE": ..., "3GLCM_CONTRAST_AVE": ...} from the definition.""" + roi = mask > 0 + mx = float(inten[roi].max()) + lv = np.clip(np.floor(DEPTH / mx * inten.astype(np.float64) + 1.0), 1, DEPTH).astype(np.int64) + i_idx, j_idx = np.indices((DEPTH, DEPTH)) + asm, con = [], [] + for dz, dy, dx in OFFSETS: + a = (slice(max(0, -dz), Z - max(0, dz)), slice(max(0, -dy), Y - max(0, dy)), slice(max(0, -dx), X - max(0, dx))) + b = (slice(max(0, dz), Z - max(0, -dz)), slice(max(0, dy), Y - max(0, -dy)), slice(max(0, dx), X - max(0, -dx))) + both = roi[a] & roi[b] + M = np.zeros((DEPTH, DEPTH)) + np.add.at(M, (lv[a][both] - 1, lv[b][both] - 1), 1.0) + p = M / M.sum() + asm.append((p ** 2).sum()) + con.append((((i_idx - j_idx) ** 2) * p).sum()) + return {"3GLCM_ASM_AVE": float(np.mean(asm)), "3GLCM_CONTRAST_AVE": float(np.mean(con))} + + +def _assert_matches_definition(tmp_path, mask): + inten = np.where(mask > 0, _volume(), 0).astype(np.uint32) + ip, mp = tmp_path / "i.ome.tif", tmp_path / "m.ome.tif" + tifffile.imwrite(str(ip), inten, metadata={"axes": "ZYX"}) + tifffile.imwrite(str(mp), mask, metadata={"axes": "ZYX"}) + want = _reference(inten, mask) + for side, limit in (("in RAM", RAM_LIMIT_LARGE_MB), ("out of core", RAM_LIMIT_OOC_MB)): + df = nyxus.Nyxus3D(["*3D_GLCM*"], ram_limit=limit).featurize_files([str(ip)], [str(mp)], False) + assert len(df) == 1 + got = df.iloc[0] + bad = [(f, float(got[f]), w) for f, w in want.items() if abs(float(got[f]) - w) > 1e-9 * abs(w)] + assert not bad, "%s: 3D GLCM parts from the definition: %r" % (side, bad) + + +def _box_cells(mask): + zz, yy, xx = mask.nonzero() + return (np.ptp(zz) + 1) * (np.ptp(yy) + 1) * (np.ptp(xx) + 1) + + +# the ellipsoid leaves background in its bounding box +def test_3d_glcm_matlab_background_analytic(tmp_path): + mask = _ellipsoid() + assert _box_cells(mask) > mask.sum(), "the fixture must leave background inside its bounding box" + _assert_matches_definition(tmp_path, mask) + + +# negative case: a ROI that fills its bounding box has no background to count +def test_3d_glcm_matlab_box_analytic(tmp_path): + mask = _box() + assert _box_cells(mask) == mask.sum(), "the fixture must fill its bounding box" + _assert_matches_definition(tmp_path, mask) diff --git a/tests/python/test_3d_glcm_pyradiomics.py b/tests/python/test_3d_glcm_pyradiomics.py new file mode 100644 index 000000000..4a213c14f --- /dev/null +++ b/tests/python/test_3d_glcm_pyradiomics.py @@ -0,0 +1,57 @@ +"""3D GLCM against PyRadiomics 3.0.1 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning they are +the ROI's bin 1 like any other voxel at its lowest level. The control moves the volume's minimum to a +voxel outside the ROI's bounding box, so the same ROI is stored without a 0. PyRadiomics reads the ROI's +own intensities and gives both phantoms the same values, so one table pins both. What this +discriminates: a family that bins a stored 0 to level 0 reads those voxels as background, or shifts +every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +The logarithmic features (3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE, 3GLCM_SUMENTROPY_AVE) carry Nyxus' fast_log10 approximation, a residual +of the order of 1e-3 that the family's other PyRadiomics tests band; they are left out here so +every pin holds at rel 1e-9. + +Goldens: binCount=8, no resampling, weightingNorm=None, from tests/vetting/oracles/gen_glcm3d_pyradiomics.py, +which re-verifies GLCM_3D_VOLMIN_PYRADIOMICS below on every run. + +Kind: *pyradiomics* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# PyRadiomics 3.0.1 on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +GLCM_3D_VOLMIN_PYRADIOMICS = { + "3GLCM_ACOR_AVE": 22.881028955947695, + "3GLCM_ASM_AVE": 0.018426882097042536, + "3GLCM_CLUPROM_AVE": 296.1317852575256, + "3GLCM_CLUSHADE_AVE": -2.6224476716790366, + "3GLCM_CLUTEND_AVE": 11.26684347438195, + "3GLCM_CONTRAST_AVE": 11.30257334990674, + "3GLCM_CORRELATION_AVE": -0.0015127185740918584, + "3GLCM_DIFAVE_AVE": 2.719947376686564, + "3GLCM_DIFVAR_AVE": 3.894859125384144, + "3GLCM_ID_AVE": 0.38579892103265034, + "3GLCM_IDM_AVE": 0.2967164396584654, + "3GLCM_IDMN_AVE": 0.8718309682097499, + "3GLCM_IDN_AVE": 0.7712322067003375, + "3GLCM_IV_AVE": 0.2839973830578059, + "3GLCM_JAVE_AVE": 4.784279883150361, + "3GLCM_JMAX_AVE": 0.040581520437353, + "3GLCM_JVAR_AVE": 5.642354206072174, + "3GLCM_SUMAVERAGE_AVE": 9.56855976630072, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_glcm_volmin_pyradiomics(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_GLCM*"], phantom, side, tmp_path) + assert_volmin_matches(row, GLCM_3D_VOLMIN_PYRADIOMICS, 1e-9, "3D GLCM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_gldm_pyradiomics.py b/tests/python/test_3d_gldm_pyradiomics.py new file mode 100644 index 000000000..1836863e0 --- /dev/null +++ b/tests/python/test_3d_gldm_pyradiomics.py @@ -0,0 +1,52 @@ +"""3D GLDM against PyRadiomics 3.0.1 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning they are +the ROI's bin 1 like any other voxel at its lowest level. The control moves the volume's minimum to a +voxel outside the ROI's bounding box, so the same ROI is stored without a 0. PyRadiomics reads the ROI's +own intensities and gives both phantoms the same values, so one table pins both. What this +discriminates: a family that bins a stored 0 to level 0 reads those voxels as background, or shifts +every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +The logarithmic features (3GLDM_DE) carry Nyxus' fast_log10 approximation, a residual +of the order of 1e-3 that the family's other PyRadiomics tests band; they are left out here so +every pin holds at rel 1e-9. + +Goldens: binCount=8, no resampling, weightingNorm=None, from tests/vetting/oracles/gen_gldm3d_pyradiomics.py, +which re-verifies GLDM_3D_VOLMIN_PYRADIOMICS below on every run. + +Kind: *pyradiomics* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# PyRadiomics 3.0.1 on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +GLDM_3D_VOLMIN_PYRADIOMICS = { + "3GLDM_DN": 95.43214285714286, + "3GLDM_DNN": 0.17041454081632654, + "3GLDM_DV": 3.170599489795918, + "3GLDM_GLN": 73.86785714285715, + "3GLDM_GLV": 5.647755102040816, + "3GLDM_HGLE": 28.414285714285715, + "3GLDM_LDE": 16.053571428571427, + "3GLDM_LDHGLE": 571.8785714285714, + "3GLDM_LDLGLE": 1.8839352147108843, + "3GLDM_LGLE": 0.16519536311548427, + "3GLDM_SDE": 0.19885432544311835, + "3GLDM_SDHGLE": 4.976939775800455, + "3GLDM_SDLGLE": 0.03671006037664267, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_gldm_volmin_pyradiomics(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_GLDM*"], phantom, side, tmp_path) + assert_volmin_matches(row, GLDM_3D_VOLMIN_PYRADIOMICS, 1e-9, "3D GLDM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_gldzm_mirp.py b/tests/python/test_3d_gldzm_mirp.py new file mode 100644 index 000000000..c97148a40 --- /dev/null +++ b/tests/python/test_3d_gldzm_mirp.py @@ -0,0 +1,52 @@ +"""3D GLDZM against MIRP fixed_bin_number 8 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning -- IBSI's +fixed bin number, which MIRP computes itself -- they are the ROI's bin 1 like any other voxel at its +lowest level. The control moves the volume's minimum to a voxel outside the ROI's bounding box, so the +same ROI is stored without a 0. MIRP reads the ROI's own intensities and gives both phantoms the same +values, so one table pins both. What this discriminates: a family that bins a stored 0 to level 0 and +then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it +still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +Goldens: by_slice=False, base_discretisation_method="fixed_bin_number", n_bins=8, from +tests/vetting/oracles/gen_gldzm3d_mirp.py, which re-verifies GLDZM_3D_VOLMIN_MIRP below on every run. + +Kind: *mirp* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# MIRP fixed_bin_number on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +GLDZM_3D_VOLMIN_MIRP = { + "3GLDZM_GLNU": 13.685714285714285, + "3GLDZM_GLNUN": 0.13034013605442177, + "3GLDZM_GLV": 5.067210884353742, + "3GLDZM_HGLZE": 23.19047619047619, + "3GLDZM_LDE": 1.561904761904762, + "3GLDZM_LDHGLE": 31.485714285714284, + "3GLDZM_LDLGLE": 0.3926128792786956, + "3GLDZM_LGLZE": 0.2178823021272001, + "3GLDZM_SDE": 0.9018518518518518, + "3GLDZM_SDHGLE": 21.58227513227513, + "3GLDZM_SDLGLE": 0.1875565067517307, + "3GLDZM_ZDE": 3.5395774379847715, + "3GLDZM_ZDNU": 81.53333333333333, + "3GLDZM_ZDNUN": 0.7765079365079365, + "3GLDZM_ZDV": 0.21188208616780047, + "3GLDZM_ZP": 0.1875, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_gldzm_volmin_mirp(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_GLDZM*"], phantom, side, tmp_path) + assert_volmin_matches(row, GLDZM_3D_VOLMIN_MIRP, 1e-9, "3D GLDZM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_glrlm_pyradiomics.py b/tests/python/test_3d_glrlm_pyradiomics.py new file mode 100644 index 000000000..0fc1d13c1 --- /dev/null +++ b/tests/python/test_3d_glrlm_pyradiomics.py @@ -0,0 +1,54 @@ +"""3D GLRLM against PyRadiomics 3.0.1 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning they are +the ROI's bin 1 like any other voxel at its lowest level. The control moves the volume's minimum to a +voxel outside the ROI's bounding box, so the same ROI is stored without a 0. PyRadiomics reads the ROI's +own intensities and gives both phantoms the same values, so one table pins both. What this +discriminates: a family that bins a stored 0 to level 0 reads those voxels as background, or shifts +every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +The logarithmic features (3GLRLM_RE_AVE) carry Nyxus' fast_log10 approximation, a residual +of the order of 1e-3 that the family's other PyRadiomics tests band; they are left out here so +every pin holds at rel 1e-9. + +Goldens: binCount=8, no resampling, weightingNorm=None, from tests/vetting/oracles/gen_glrlm3d_pyradiomics.py, +which re-verifies GLRLM_3D_VOLMIN_PYRADIOMICS below on every run. + +Kind: *pyradiomics* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# PyRadiomics 3.0.1 on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +GLRLM_3D_VOLMIN_PYRADIOMICS = { + "3GLRLM_GLN_AVE": 65.60159853259819, + "3GLRLM_GLNN_AVE": 0.13010124589226885, + "3GLRLM_GLV_AVE": 5.583584348280135, + "3GLRLM_HGLRE_AVE": 27.916001064711843, + "3GLRLM_LGLRE_AVE": 0.16877635951279563, + "3GLRLM_LRE_AVE": 1.4286252340245666, + "3GLRLM_LRHGLE_AVE": 43.39820759601726, + "3GLRLM_LRLGLE_AVE": 0.2199225750395456, + "3GLRLM_RLN_AVE": 418.1133441240835, + "3GLRLM_RLNN_AVE": 0.8288371363404127, + "3GLRLM_RP_AVE": 0.9004120879120878, + "3GLRLM_RV_AVE": 0.194291794390713, + "3GLRLM_SRE_AVE": 0.927980602428168, + "3GLRLM_SRHGLE_AVE": 25.652855539715063, + "3GLRLM_SRLGLE_AVE": 0.1586678736288215, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_glrlm_volmin_pyradiomics(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_GLRLM*"], phantom, side, tmp_path) + assert_volmin_matches(row, GLRLM_3D_VOLMIN_PYRADIOMICS, 1e-9, "3D GLRLM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_glszm_pyradiomics.py b/tests/python/test_3d_glszm_pyradiomics.py new file mode 100644 index 000000000..0a5c13770 --- /dev/null +++ b/tests/python/test_3d_glszm_pyradiomics.py @@ -0,0 +1,54 @@ +"""3D GLSZM against PyRadiomics 3.0.1 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning they are +the ROI's bin 1 like any other voxel at its lowest level. The control moves the volume's minimum to a +voxel outside the ROI's bounding box, so the same ROI is stored without a 0. PyRadiomics reads the ROI's +own intensities and gives both phantoms the same values, so one table pins both. What this +discriminates: a family that bins a stored 0 to level 0 reads those voxels as background, or shifts +every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +The logarithmic features (3GLSZM_ZE) carry Nyxus' fast_log10 approximation, a residual +of the order of 1e-3 that the family's other PyRadiomics tests band; they are left out here so +every pin holds at rel 1e-9. + +Goldens: binCount=8, no resampling, weightingNorm=None, from tests/vetting/oracles/gen_glszm3d_pyradiomics.py, +which re-verifies GLSZM_3D_VOLMIN_PYRADIOMICS below on every run. + +Kind: *pyradiomics* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# PyRadiomics 3.0.1 on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +GLSZM_3D_VOLMIN_PYRADIOMICS = { + "3GLSZM_GLN": 13.685714285714285, + "3GLSZM_GLNN": 0.13034013605442177, + "3GLSZM_GLV": 5.067210884353742, + "3GLSZM_HGLZE": 23.19047619047619, + "3GLSZM_LAE": 169.56190476190477, + "3GLSZM_LAHGLE": 7802.114285714286, + "3GLSZM_LALGLE": 11.393171836194796, + "3GLSZM_LGLZE": 0.2178823021272001, + "3GLSZM_SAE": 0.598210506718065, + "3GLSZM_SAHGLE": 14.642090673477966, + "3GLSZM_SALGLE": 0.1060690942220315, + "3GLSZM_SZN": 35.095238095238095, + "3GLSZM_SZNN": 0.33424036281179137, + "3GLSZM_ZP": 0.1875, + "3GLSZM_ZV": 141.1174603174603, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_glszm_volmin_pyradiomics(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_GLSZM*"], phantom, side, tmp_path) + assert_volmin_matches(row, GLSZM_3D_VOLMIN_PYRADIOMICS, 1e-9, "3D GLSZM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_ngldm_mirp.py b/tests/python/test_3d_ngldm_mirp.py new file mode 100644 index 000000000..6ceb497cb --- /dev/null +++ b/tests/python/test_3d_ngldm_mirp.py @@ -0,0 +1,55 @@ +"""3D NGLDM against MIRP fixed_bin_number 8 on bench_volmin_3d, whose ROI holds the volume's lowest +intensity, and on its control bench_volmin_ctrl_3d, in RAM and out of core. + +Nyxus stores a volume offset by its lowest intensity, so the darkest voxels of this ROI are stored as +0, the value the background cells of its bounding box hold. Under PyRadiomics-style binning -- IBSI's +fixed bin number, which MIRP computes itself -- they are the ROI's bin 1 like any other voxel at its +lowest level. The control moves the volume's minimum to a voxel outside the ROI's bounding box, so the +same ROI is stored without a 0. MIRP reads the ROI's own intensities and gives both phantoms the same +values, so one table pins both. What this discriminates: a family that bins a stored 0 to level 0 and +then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it +still holds on the control. + +The out-of-core side streams the same stored intensities from an OME-TIFF Z-stack at ram_limit=0; the +NIfTI loader delivers the whole volume in one read and so cannot stream (see test_data.featurize_volmin). + +3NGLDM_DCP is left out as in the family's other MIRP tables: both tools return 1 whenever every +voxel has a same-level neighbour, so it would claim more than it shows. + +Goldens: by_slice=False, base_discretisation_method="fixed_bin_number", n_bins=8, from +tests/vetting/oracles/gen_ngldm3d_mirp.py, which re-verifies NGLDM_3D_VOLMIN_MIRP below on every run. + +Kind: *mirp* per tests/vetting/SPEC.md 4. +""" + +import pytest + +from test_data import VOLMIN_NBINS, assert_volmin_matches, featurize_volmin + +# MIRP fixed_bin_number on bench_volmin_3d at 8 bins: the same values on bench_volmin_ctrl_3d, whose ROI is the same. +NGLDM_3D_VOLMIN_MIRP = { + "3NGLDM_DCENE": 0.02431122448979592, + "3NGLDM_DCENT": 5.529960784380476, + "3NGLDM_DCNU": 95.43214285714286, + "3NGLDM_DCNUN": 0.17041454081632654, + "3NGLDM_DCV": 3.170599489795918, + "3NGLDM_GLNU": 73.86785714285715, + "3NGLDM_GLNUN": 0.13190688775510204, + "3NGLDM_GLV": 5.647755102040818, + "3NGLDM_HDE": 16.053571428571427, + "3NGLDM_HDHGLE": 571.8785714285714, + "3NGLDM_HDLGLE": 1.8839352147108843, + "3NGLDM_HGLCE": 28.414285714285715, + "3NGLDM_LDE": 0.19885432544311835, + "3NGLDM_LDHGLE": 4.976939775800456, + "3NGLDM_LDLGLE": 0.03671006037664266, + "3NGLDM_LGLCE": 0.16519536311548427, +} + + +@pytest.mark.parametrize("side", ["in_ram", "out_of_core"]) +@pytest.mark.parametrize("phantom", ["volmin", "ctrl"]) +def test_3d_ngldm_volmin_mirp(tmp_path, phantom, side): + assert VOLMIN_NBINS == 8 + row = featurize_volmin(["*3D_NGLDM*"], phantom, side, tmp_path) + assert_volmin_matches(row, NGLDM_3D_VOLMIN_MIRP, 1e-9, "3D NGLDM on %s, %s" % (phantom, side)) diff --git a/tests/python/test_3d_texture_background_mechanics.py b/tests/python/test_3d_texture_background_mechanics.py index 356537670..b394ee3fa 100644 --- a/tests/python/test_3d_texture_background_mechanics.py +++ b/tests/python/test_3d_texture_background_mechanics.py @@ -4,7 +4,9 @@ Under MATLAB-style binning -- a positive grey depth, 64 by default -- intensity 0 bins to level 1, the level the ROI's darkest voxels bin to as well, so the binned value cannot tell the background from the ROI. 3D GLSZM, GLDM and GLRLM tell them apart by the ROI's voxel cloud, in RAM and out of -core, and these tests assert it. +core, and these tests assert it. 3D GLCM does too, but its matrix is asymmetric under MATLAB-style +binning and symmetric with no binning, so the reference below cannot judge it; test_3d_glcm_analytic.py +holds it to the definition instead. The reference is the same ROI with its MATLAB levels written into the image and no binning. There the background is intensity 0 and every ROI voxel is level 1 or above, so nothing is ambiguous. A diff --git a/tests/python/test_data.py b/tests/python/test_data.py index 379da0655..766c346ea 100644 --- a/tests/python/test_data.py +++ b/tests/python/test_data.py @@ -1,3 +1,5 @@ +import pathlib + import numpy as np intens = np.array([ @@ -123,3 +125,62 @@ def write_disk64_pair(tmp_path, tifffile, as_dirs=True): tifffile.imwrite(str(ip), inten) tifffile.imwrite(str(sp), mask) return str(ip), str(sp) + + +# bench_volmin_3d and its control bench_volmin_ctrl_3d: an ellipsoid ROI whose bounding box has +# background in it, holding the volume's lowest intensity (the control moves that minimum to a voxel +# outside the box, leaving the ROI unchanged). Built and described by +# tests/vetting/oracles/volmin_phantom.py, which writes the NIfTI files and pins the oracles on them. +# Every 3D texture family reads it, so it lives here rather than in one family's module. +VOLMIN_DIR = pathlib.Path(__file__).resolve().parent.parent / "data" / "nifti" / "phantoms" +VOLMIN_INTEN = str(VOLMIN_DIR / "volmin_inten.nii") +VOLMIN_CTRL_INTEN = str(VOLMIN_DIR / "volmin_ctrl_inten.nii") +VOLMIN_MASK = str(VOLMIN_DIR / "volmin_mask.nii") +VOLMIN_LABEL = 1 +VOLMIN_NBINS = 8 # the bin count the oracles are pinned at; Nyxus' depth is its negative +VOLMIN_RAM_LIMIT_LARGE_MB = 1000 # the in-RAM side's ram_limit, as in test_ooc_mechanics.py +VOLMIN_PHANTOMS = {"volmin": VOLMIN_INTEN, "ctrl": VOLMIN_CTRL_INTEN} + + +def _read_nifti_volume(path): + """-> the (z, y, x) array of an uncompressed single-file NIfTI-1 of datatype uint8 or int16.""" + raw = open(path, "rb").read() + dim = np.frombuffer(raw, np.int16, 8, 40) + dtype = {2: np.uint8, 4: np.int16}[int(np.frombuffer(raw, np.int16, 1, 70)[0])] + off = int(np.frombuffer(raw, np.float32, 1, 108)[0]) + nx, ny, nz = int(dim[1]), int(dim[2]), int(dim[3]) + return np.frombuffer(raw, dtype, nx * ny * nz, off).reshape((nz, ny, nx)) + + +def featurize_volmin(groups, phantom, side, tmp_path, metaparams=()): + """-> the one row Nyxus3D gives `phantom` ("volmin" or "ctrl") at coarse depth -VOLMIN_NBINS. + + side "in_ram" reads the NIfTI pair. side "out_of_core" cannot -- NIfTI delivers the whole volume in + one read -- so it writes the intensities as a uint16 OME-TIFF Z-stack stored the way the NIfTI + loader stores them, offset by the volume's lowest intensity, and streams it at ram_limit=0, which + every ROI footprint reaches. + """ + import nyxus + if side == "in_ram": + pair, ram_limit = (VOLMIN_PHANTOMS[phantom], VOLMIN_MASK), VOLMIN_RAM_LIMIT_LARGE_MB + else: + import tifffile + inten = _read_nifti_volume(VOLMIN_PHANTOMS[phantom]).astype(np.int32) + ip, mp = tmp_path / (phantom + "_i.ome.tif"), tmp_path / (phantom + "_m.ome.tif") + tifffile.imwrite(str(ip), (inten - inten.min()).astype(np.uint16), metadata={"axes": "ZYX"}) + tifffile.imwrite(str(mp), _read_nifti_volume(VOLMIN_MASK).astype(np.uint16), metadata={"axes": "ZYX"}) + pair, ram_limit = (str(ip), str(mp)), 0 + nyx = nyxus.Nyxus3D(groups, ram_limit=ram_limit, coarse_gray_depth=-VOLMIN_NBINS) + for m in metaparams: + nyx.set_metaparam(m) + df = nyx.featurize_files([pair[0]], [pair[1]], False) + assert len(df) == 1, len(df) + return df.iloc[0] + + +def assert_volmin_matches(row, want, reltol, what): + """Every pinned feature of `want` in `row` within `reltol`, naming each that is not.""" + missing = [f for f in want if f not in row.index] + assert not missing, "%s: no column for %r" % (what, missing) + bad = [(f, float(row[f]), w) for f, w in want.items() if abs(float(row[f]) - w) > reltol * max(abs(w), 1e-300)] + assert not bad, "%s parts from its oracle: %r" % (what, bad) diff --git a/tests/test_3d_glcm_regression.h b/tests/test_3d_glcm_regression.h index 1681ed935..2a5e39994 100644 --- a/tests/test_3d_glcm_regression.h +++ b/tests/test_3d_glcm_regression.h @@ -325,10 +325,11 @@ void test_3d_glcm_sum_variance_regression() // ----------------------------------------------------------------------------------------------- // "grey64" profile: the same phantom as above (ut_inten.nii / ut_mask57.nii, label 57), but -// GREYDEPTH=64 with GLCM_GREYDEPTH=+64 -- a positive value, which bin_intensities_3d -// (texture_feature.h) routes through matlab_grey_binning (a FIXED 64-level count) rather than the -// -100 bincount profile the rest of this file uses (radiomics_grey_binning, bin count derived from -// the ROI's own min/max). +// GREYDEPTH=64 with GLCM_GREYDEPTH=+64 -- a positive value, which bin_roi_3d (3d_ooc_volume.h) +// routes through matlab_grey_binning (a FIXED 64-level count) rather than the -100 bincount +// profile the rest of this file uses (radiomics_grey_binning, bin count derived from the ROI's own +// min/max). The ROI's voxels take levels 1..64 and the rest of its bounding box level 0, which pairs +// with nothing; tests/python/test_3d_glcm_analytic.py holds that to the definition. // // Every one of these 36 features is independently oracle-vetted against PyRadiomics elsewhere in // test_3d_glcm_pyradiomics.h, under the -100 bincount profile (some directly, some by the @@ -337,44 +338,67 @@ void test_3d_glcm_sum_variance_regression() // History: tests/vetting/audit/glcm_3d_golden_regen.md, "grey64 table and the retired Wave-9 sweep". static const ref_vals_map> glcm_3d_regression_grey64_ref_vals { - { "3GLCM_ACOR_AVE", { 896.29490954682888 } }, - { "3GLCM_ASM_AVE", { 0.21714923037245615 } }, - { "3GLCM_CLUPROM_AVE", { 5319702.1464416385 } }, - { "3GLCM_CLUSHADE_AVE", { 25300.544725496744 } }, - { "3GLCM_CLUTEND_AVE", { 1830.7699876860852 } }, - { "3GLCM_CONTRAST_AVE", { 190.39105377069197 } }, - { "3GLCM_CORRELATION_AVE", { 0.81160543314537192 } }, - { "3GLCM_DIFAVE_AVE", { 4.4826978263468851 } }, - { "3GLCM_DIFENTRO_AVE", { 2.5804645841819687 } }, - { "3GLCM_DIFVAR_AVE", { 168.82038645655439 } }, - { "3GLCM_DIS", { 5.5662607942292563, 5.2865125777406536, 5.5662607942292563, 3.5205463112065347, 3.2058935920047036, 3.5205463112065347, 5.5662607942292563, 5.2865125777406536, 5.5662607942292563, 4.6920801473460996, 4.4260407115349301, 4.6920801473460996, 1.379816189466244 } }, - { "3GLCM_DIS_AVE", { 4.4826978263468824 } }, - { "3GLCM_ENERGY", { 0.20619709037207257, 0.21210950671886142, 0.20619709037207257, 0.22347189327232553, 0.229768029906674, 0.22347189327232553, 0.20619709037207257, 0.21210950671886142, 0.20619709037207257, 0.21657166507454639, 0.22249608735556295, 0.21657166507454639, 0.2415813859599367 } }, - { "3GLCM_ENERGY_AVE", { 0.21714923037245615 } }, - { "3GLCM_ENTROPY", { 6.1375193094015223, 6.0251268596431471, 6.1375193094015223, 5.6356261936885357, 5.5229037686481623, 5.6356261936885357, 6.1375193094015223, 6.0251268596431471, 6.1375193094015223, 5.9202631504971848, 5.8126798565436344, 5.9202631504971848, 4.8177837873733909 } }, - { "3GLCM_ENTROPY_AVE", { 5.8358059275253087 } }, - { "3GLCM_HOM1", { 0.63159286085358357, 0.67511464571418467, 0.63159286085358357, 0.675209797165082, 0.7178512712427948, 0.675209797165082, 0.63159286085358357, 0.67511464571418467, 0.63159286085358357, 0.65283716836970751, 0.69041197263012255, 0.65283716836970751, 0.77822827662266392 } }, - { "3GLCM_HOM1_AVE", { 0.67070662972368189 } }, - { "3GLCM_HOM2", { 0.59196175760722125, 0.64232872280698583, 0.59196175760722125, 0.63506326531940249, 0.68470533035896952, 0.63506326531940249, 0.59196175760722125, 0.64232872280698583, 0.59196175760722125, 0.61310667832992871, 0.65700403974706201, 0.61310667832992871, 0.75964624124070679 } }, - { "3GLCM_IDMN_AVE", { 0.97393106857854816 } }, - { "3GLCM_IDM_AVE", { 0.63463076728371071 } }, - { "3GLCM_IDN_AVE", { 0.95491658377679667 } }, - { "3GLCM_ID_AVE", { 0.67070662972368211 } }, - { "3GLCM_INFOMEAS1_AVE", { -0.44521529228752316 } }, - { "3GLCM_INFOMEAS2_AVE", { 0.97909293489987548 } }, - { "3GLCM_IV_AVE", { 0.15630830580149896 } }, - { "3GLCM_JAVE_AVE", { 22.049501181077645 } }, - { "3GLCM_JE_AVE", { 5.83580592757035 } }, - { "3GLCM_JMAX_AVE", { 0.46494916987187934 } }, - { "3GLCM_JVAR_AVE", { 505.29026036419413 } }, - { "3GLCM_SUMAVERAGE_AVE", { 44.099002362155289 } }, - { "3GLCM_SUMENTROPY_AVE", { 4.3772246057690438 } }, - { "3GLCM_SUMVARIANCE", { 1783.3177119109412, 1796.9249632904919, 1783.3177119109412, 1872.6626392475214, 1887.8346987420691, 1872.6626392475214, 1783.3177119109412, 1796.9249632904919, 1783.3177119109412, 1820.9267907064923, 1833.7216725021183, 1820.9267907064923, 1964.1538345421473 } }, - { "3GLCM_SUMVARIANCE_AVE", { 1830.7699876860852 } }, - { "3GLCM_VARIANCE", { 504.75832684863678, 506.44120833399279, 504.75832684863678, 504.89933309869377, 506.49086530867982, 504.89933309869377, 504.75832684863678, 506.44120833399279, 504.75832684863678, 504.73432274406343, 506.30964057188811, 504.73432274406343, 504.78984310590351 } }, - { "3GLCM_VARIANCE_AVE", { 505.29026036419378 } }, + { "3GLCM_ACOR_AVE", { 1850.8335249149752 } }, + { "3GLCM_ASM_AVE", { 0.0030350561133472989 } }, + { "3GLCM_CLUPROM_AVE", { 550983.97325296595 } }, + { "3GLCM_CLUSHADE_AVE", { 1238.9760409253222 } }, + { "3GLCM_CLUTEND_AVE", { 549.80591230753862 } }, + { "3GLCM_CONTRAST_AVE", { 19.016529791925713 } }, + { "3GLCM_CORRELATION_AVE", { 0.93278972762567192 } }, + { "3GLCM_DIFAVE_AVE", { 2.9100685893942364 } }, + { "3GLCM_DIFENTRO_AVE", { 3.0538649265280329 } }, + { "3GLCM_DIFVAR_AVE", { 10.005140883354468 } }, + { "3GLCM_DIS", { 3.6053408854667164, 3.2839273033734186, 3.6053408854667164, 2.399984767707537, 2.061109849345141, 2.399984767707537, 3.6053408854667164, 3.2839273033734186, 3.6053408854667164, 3.086066240557813, 2.7754196143709273, 3.086066240557813, 1.0330420332645887 } }, + { "3GLCM_DIS_AVE", { 2.9100685893942355 } }, + { "3GLCM_ENERGY", { 0.0023030621867733323, 0.0028088930799635334, 0.0023030621867733323, 0.0030448295764018982, 0.0035340118946216316, 0.0030448295764018982, 0.0023030621867733323, 0.0028088930799635334, 0.0023030621867733323, 0.0026388187617093438, 0.0030383743490557998, 0.0026388187617093438, 0.0066860116465945725 } }, + { "3GLCM_ENERGY_AVE", { 0.0030350561133472989 } }, + { "3GLCM_ENTROPY", { 9.4153193770961963, 9.299903315485146, 9.4153193770961963, 8.7578969505445148, 8.6423403764115676, 8.7578969505445148, 9.4153193770961963, 9.299903315485146, 9.4153193770961963, 9.1637111582840536, 9.0566213630012591, 9.1637111582840536, 7.4438525203583197 } }, + { "3GLCM_ENTROPY_AVE", { 9.0190088166756421 } }, + { "3GLCM_HOM1", { 0.36892514882970728, 0.45044986312487578, 0.36892514882970728, 0.41424874300616815, 0.49224180198970136, 0.41424874300616815, 0.36892514882970728, 0.45044986312487578, 0.36892514882970728, 0.39005648807915821, 0.45950108578725052, 0.39005648807915821, 0.58069852668437139 } }, + { "3GLCM_HOM1_AVE", { 0.42443478447696592 } }, + { "3GLCM_HOM2", { 0.28872829324757127, 0.38383297610972528, 0.28872829324757127, 0.33348704011686431, 0.42513980234144694, 0.33348704011686431, 0.28872829324757127, 0.38383297610972528, 0.28872829324757127, 0.30925413808751828, 0.39117578581244239, 0.30925413808751828, 0.54369352661018644 } }, + { "3GLCM_ID_AVE", { 0.42443478447696553 } }, + { "3GLCM_IDM_AVE", { 0.35139004587558276 } }, + { "3GLCM_IDMN_AVE", { 0.99550994848928454 } }, + { "3GLCM_IDN_AVE", { 0.95855194861389903 } }, + { "3GLCM_INFOMEAS1_AVE", { -0.32870346918013804 } }, + { "3GLCM_INFOMEAS2_AVE", { 0.97988073861294089 } }, + { "3GLCM_IV_AVE", { 0.32337710991277124 } }, + { "3GLCM_JAVE_AVE", { 41.44965196578697 } }, + { "3GLCM_JE_AVE", { 9.0190088166756421 } }, + { "3GLCM_JMAX_AVE", { 0.016882088924277859 } }, + { "3GLCM_JVAR_AVE", { 142.20561052486624 } }, + { "3GLCM_SUMAVERAGE_AVE", { 82.89930393157394 } }, + { "3GLCM_SUMENTROPY_AVE", { 6.360910266199463 } }, + { "3GLCM_SUMVARIANCE", { 534.9226533913079, 542.12060325402661, 534.9226533913079, 559.99883944107921, 567.68016633279228, 559.99883944107921, 534.9226533913079, 542.12060325402661, 534.9226533913079, 546.51186802586574, 553.43733294451715, 546.51186802586574, 589.40612571351767 } }, + { "3GLCM_SUMVARIANCE_AVE", { 549.80591230753862 } }, + { "3GLCM_VARIANCE", { 140.45030020213335, 141.90140614909257, 140.45030020213335, 142.39253925859447, 143.9625353374569, 142.39253925859447, 140.45030020213335, 141.90140614909257, 140.45030020213335, 141.72606113778599, 143.10885929152289, 141.72606113778599, 147.7603282948017 } }, + { "3GLCM_VARIANCE_AVE", { 142.20561052486622 } }, }; +// Regenerates glcm_3d_regression_grey64_ref_vals at full precision, in the table's own shape: one +// value for an _AVE feature, the 13 angled values otherwise. +// runAllTests --gtest_filter=*3D_GLCM_GREY64_DUMP_REGRESSION* +void test_3d_glcm_grey64_dump_regression() +{ + Environment e; + int label = -1, fcode = -1; + run_3d_glcm_feature_pipeline(e, "3GLCM_ACOR_AVE", Nyxus::Feature3D::GLCM_ACOR_AVE, 64, 64, label, fcode); + if (::testing::Test::HasFatalFailure()) return; + + for (const auto& kv : glcm_3d_regression_grey64_ref_vals) + { + int fc = -1; + ASSERT_TRUE(e.theFeatureSet.find_3D_FeatureByString(kv.first, fc)) << kv.first; + const auto& v = e.roiData[label].fvals[fc]; + const std::size_t n = kv.second.size() == 1 ? 1 : v.size(); + std::cout << "[3DGLCM-GREY64-REGEN]\t{ \"" << kv.first << "\", { "; + for (std::size_t i = 0; i < n; i++) + std::cout << (i ? ", " : "") << std::setprecision(17) << v[i]; + std::cout << " } },\n"; + } +} + // Same shared pipeline as above; checks every angled value against the table instead of averaging. static void assert_3d_glcm_feature_grey64_regression (const Nyxus::Feature3D& expecting_fcode, const std::string& fname) { diff --git a/tests/test_3d_gldm_pyradiomics.h b/tests/test_3d_gldm_pyradiomics.h index b2791d4f6..9c44ffbeb 100644 --- a/tests/test_3d_gldm_pyradiomics.h +++ b/tests/test_3d_gldm_pyradiomics.h @@ -473,8 +473,10 @@ static void assert_3d_gldm_feature_pyradiomics (const Nyxus::Feature3D& expectin // The matrix under the fourteen features, read off the feature object the fourteen oracle assertions // run through: this assertion and those describe one run of one phantom rather than two, and a // hand-written copy of the phantom would keep passing after the loader started producing something -// else. The definition arm beside it re-bins the cube that run read, with the same -// bin_intensities_3d() calculate() calls, and walks the neighbourhood from the definition. +// else. The definition arm beside it re-bins the cube that run read with the cube-wide +// bin_intensities_3d(), which on this phantom gives every ROI voxel the level calculate()'s +// bin_roi_3d() gives it, no ROI voxel being stored as 0, and walks the neighbourhood from the +// definition. void test_3d_gldm_matrix_pyradiomics() { auto [ipath, mpath, label] = get_3d_compat_phantom(); diff --git a/tests/test_3d_gldzm_mechanics.h b/tests/test_3d_gldzm_mechanics.h index ddd72a99d..49aaa7dc5 100644 --- a/tests/test_3d_gldzm_mechanics.h +++ b/tests/test_3d_gldzm_mechanics.h @@ -3,11 +3,11 @@ // 3D GLDZM mechanics: what the family does with a ROI voxel whose grey level is 0, and the bound on // the out-of-core border distance (at the end of the file). // -// A GLDZM grey level is 1-based, and two of the three binning schemes hand back a 0 for a voxel that -// is genuinely the ROI's: `IBSI=true` bins nothing, so a raw intensity of 0 stays 0, and the -// radiomics scheme maps 0 to 0 by construction. Only the MATLAB scheme cannot, because it sends 0 to -// level 1. `prepare_GLDZM_matrix_kit` lifts the ROI's levels by one where that happens, which keeps -// those voxels in a zone. +// A GLDZM grey level is 1-based, and one of the three binning schemes hands back a 0 for a voxel that +// is genuinely the ROI's: `IBSI=true` bins nothing, so a raw intensity of 0 stays 0. +// `prepare_GLDZM_matrix_kit` lifts the ROI's levels by one where that happens, which keeps those +// voxels in a zone. The radiomics and MATLAB schemes put every ROI voxel at level 1 or more, a raw 0 +// included, so they never lift; the radiomics case below pins that. // // bench_gldzm_zerolevel_3d is the fixture that separates lifting them from dropping them, and it is // the only one in the family that can: the compatibility phantom's levels are 1..8 and the segmented @@ -71,11 +71,36 @@ static const double gldzm_3d_mechanics_tolerance = 1.e-9; static const double gldzm_3d_mechanics_zones = 2.0; static const double gldzm_3d_mechanics_roi_voxels = 64.0; +// The radiomics scheme at a bin count of 5 puts the raw levels 0 and 5 in bins 1 and 5 (IBSI's fixed +// bin number, floor(5 x / 5) + 1, the top level clipped into the last bin), so the same two zones sit +// in rows 1 and 5. Only the grey-level-weighted entries differ from the table above. +static const ref_vals_map gldzm_3d_mechanics_radiomics_ref_vals{ + {"3GLDZM_SDE", 1.0}, + {"3GLDZM_LDE", 1.0}, + {"3GLDZM_LGLZE", 0.52}, // (1/1^2 + 1/5^2) / 2 + {"3GLDZM_HGLZE", 13.0}, // (1^2 + 5^2) / 2 + {"3GLDZM_SDLGLE", 0.52}, + {"3GLDZM_SDHGLE", 13.0}, + {"3GLDZM_LDLGLE", 0.52}, + {"3GLDZM_LDHGLE", 13.0}, + {"3GLDZM_GLNU", 1.0}, + {"3GLDZM_GLNUN", 0.5}, + {"3GLDZM_ZDNU", 2.0}, + {"3GLDZM_ZDNUN", 1.0}, + {"3GLDZM_ZP", 0.03125}, + {"3GLDZM_GLM", 3.0}, // (1 + 5) / 2 + {"3GLDZM_GLV", 4.0}, // ((1-3)^2 + (5-3)^2) / 2 + {"3GLDZM_ZDM", 1.0}, + {"3GLDZM_ZDV", 0.0}, + {"3GLDZM_ZDE", 1.0}, +}; + // The derived table and the zone count, asserted against one extraction. -static void assert_3d_gldzm_zero_level_voxels_are_zoned (const std::vector>& fvals) +static void assert_3d_gldzm_zero_level_voxels_are_zoned (const std::vector>& fvals, + const ref_vals_map& want = gldzm_3d_mechanics_ref_vals) { Environment e; - for (const auto& nv : gldzm_3d_mechanics_ref_vals) + for (const auto& nv : want) { int fcode = -1; ASSERT_TRUE(e.theFeatureSet.find_3D_FeatureByString(nv.first, fcode)) << nv.first; @@ -103,20 +128,18 @@ void test_3d_gldzm_zero_level_voxels_are_zoned_mechanics() } // The same fixture through the radiomics scheme, which gathers the ROI's grey levels as a set rather -// than as a 1..max ladder, so its lift is a separate code path from the no-binning point's. -// -// At a bin count of 5 the scheme maps the fixture's raw levels onto themselves: `to_grayscale_radiomix` -// sends 0 to 0 by construction, and 5 over a bin width of (5-0)/5 = 1 to bin 6, which clips into the -// last bin, 5. The lift then makes them 1 and 6 -- the levels of the no-binning point -- so the -// derived table above applies unchanged. A set gathered without the lift would hold 0 and 5, and a -// level-1 zone would have no row to go in. +// than as a 1..max ladder. A ROI voxel at raw intensity 0 is the ROI's lowest level and goes to bin 1 +// like any other (Nyxus::roi_voxel_binning), so nothing is lifted and the levels are 1 and 5. What +// this discriminates: a scheme that sends the raw 0 to level 0 and then lifts every level by one puts +// the zones in rows 1 and 6 and fails LGLZE, HGLZE, GLM and GLV; one that drops the level-0 voxels +// leaves one zone and fails ZP. void test_3d_gldzm_zero_level_voxels_are_zoned_radiomics_mechanics() { auto [ipath, mpath, label] = get_3d_gldzm_zerolevel_phantom(); std::vector> fvals; ASSERT_NO_FATAL_FAILURE(extract_3d_gldzm(fvals, ipath, mpath, label, make_gldzm3d_settings(-5, false))); - assert_3d_gldzm_zero_level_voxels_are_zoned (fvals); + assert_3d_gldzm_zero_level_voxels_are_zoned (fvals, gldzm_3d_mechanics_radiomics_ref_vals); } // GREYDEPTH=0 and IBSI=true are two ways of asking for the same thing -- calculate() overwrites the diff --git a/tests/test_3d_ngtdm_regression.h b/tests/test_3d_ngtdm_regression.h index b2f2c0a62..c48c4cc26 100644 --- a/tests/test_3d_ngtdm_regression.h +++ b/tests/test_3d_ngtdm_regression.h @@ -7,9 +7,10 @@ // // Regenerate with test_3d_ngtdm_dump_regression() below. // -// At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel -// binned there is not a matrix row of its own, but it still counts towards its neighbours' -// neighbourhood means. That is Nyxus' convention for this family and is what these values are of. +// At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest +// of the bounding box level 0, and since 0 is then among the levels the family lifts every level by +// one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix +// and it counts towards its neighbours' neighbourhood means. These values are of that state. // Only what nothing this file already includes supplies: for the dump helper's // setprecision. , , , and gtest arrive through the common header @@ -21,11 +22,11 @@ static const ref_vals_map ngtdm_3d_regression_ref_vals { - {"3NGTDM_COARSENESS", 4.1746559837294642e-05}, - {"3NGTDM_CONTRAST", 0.63226607482802633}, - {"3NGTDM_BUSYNESS", 44.389552850401223}, - {"3NGTDM_COMPLEXITY", 2819.3512285176689}, - {"3NGTDM_STRENGTH", 0.024654440905359544} + {"3NGTDM_COARSENESS", 4.1204162221171236e-05}, + {"3NGTDM_CONTRAST", 0.64067304737766795}, + {"3NGTDM_BUSYNESS", 45.088896286519478}, + {"3NGTDM_COMPLEXITY", 2857.3201047656198}, + {"3NGTDM_STRENGTH", 0.024330922991243304} }; // Defined in test_3d_glcm_pyradiomics.h, which the translation unit includes first. diff --git a/tests/test_all.cc b/tests/test_all.cc index c05efd046..ce3da518b 100644 --- a/tests/test_all.cc +++ b/tests/test_all.cc @@ -1690,6 +1690,10 @@ TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_COARSE_GRAY_DEPTH_CLI_REFUSED_MECHANICS) ASSERT_NO_FATAL_FAILURE(test_feature_settings_coarse_gray_depth_cli_refused_mechanics()); } +TEST(TEST_NYXUS, TEST_TEXTURE_BINNING_ROI_CUBE_VOXEL_AT_ZERO_MECHANICS) { + ASSERT_NO_FATAL_FAILURE(test_texture_binning_roi_cube_voxel_at_zero_mechanics()); +} + TEST(TEST_NYXUS, TEST_FEATURE_SETTINGS_GREY_DEPTH_PARSE_RANGE_MECHANICS) { ASSERT_NO_FATAL_FAILURE(test_feature_settings_grey_depth_parse_range_mechanics()); } @@ -6138,6 +6142,7 @@ TEST(TEST_NYXUS, TEST_3D_GLCM_SUM_ENTROPY_REGRESSION) { ASSERT_NO_THROW(test_3d_ TEST(TEST_NYXUS, TEST_3D_GLCM_SUM_VARIANCE_REGRESSION) { ASSERT_NO_THROW(test_3d_glcm_sum_variance_regression()); } TEST(TEST_NYXUS, TEST_3D_GLCM_DUMP_REGRESSION) { ASSERT_NO_THROW(test_3d_glcm_dump_regression()); } +TEST(TEST_NYXUS, TEST_3D_GLCM_GREY64_DUMP_REGRESSION) { ASSERT_NO_FATAL_FAILURE(test_3d_glcm_grey64_dump_regression()); } // 3D GLCM "grey64" drift guards: named individually per feature rather than swept via TEST_P. // History: tests/vetting/audit/glcm_3d_golden_regen.md, "grey64 table and the retired Wave-9 sweep". diff --git a/tests/test_texture_binning_mechanics.h b/tests/test_texture_binning_mechanics.h index 6d5868458..4ed8274f2 100644 --- a/tests/test_texture_binning_mechanics.h +++ b/tests/test_texture_binning_mechanics.h @@ -17,7 +17,7 @@ void test_texture_binning_zero_width_range_mechanics() EXPECT_EQ (TextureFeature::to_grayscale_radiomix (7, 7, 7, 1), 1u); EXPECT_EQ (TextureFeature::to_grayscale_radiomix (0, 7, 7, 8), 0u); - // through the cube binning the 3D families call, at a negative grey depth + // through the cube-wide binning, at a negative grey depth SimpleCube I, D; I.allocate (3, 2, 2); I.fill (7); @@ -61,6 +61,38 @@ void test_texture_binning_roi_cube_places_voxels_mechanics() EXPECT_EQ (background, 9u); } +// A ROI voxel stored as 0 -- the volume's lowest intensity, which the loader offsets every intensity +// by -- is a ROI voxel like any other: PyRadiomics-style binning puts it in bin 1 and MATLAB-style +// binning at level 1, and only the cells that are not the ROI's keep level 0. With no binning its +// level is its raw value, 0. What this discriminates: a binning that treats a stored 0 as background +// leaves the voxel at 0 under PyRadiomics-style binning, where the families read 0 as background. +void test_texture_binning_roi_cube_voxel_at_zero_mechanics() +{ + LR r; + r.aabb.init_x (0); r.aabb.update_x (2); + r.aabb.init_y (0); r.aabb.update_y (0); + r.aabb.init_z (0); r.aabb.update_z (0); + r.raw_pixels_3D = { Pixel3 (0, 0, 0, 0), Pixel3 (2, 0, 0, 64) }; // x = 1 is background + r.aux_min = 0; + r.aux_max = 64; + + struct { int greydepth; PixIntens at_zero, at_max; } cases[] = { + { -4, 1, 4 }, // PyRadiomics-style: floor(4 (x - 0) / 64) + 1, the top clipped into bin 4 + { 4, 1, 4 }, // MATLAB-style: floor(4 x / 64 + 1), clipped to 1..4 + { 0, 0, 64 }, // no binning: the raw values + }; + for (const auto& c : cases) + { + SCOPED_TRACE ("greydepth " + std::to_string (c.greydepth)); + SimpleCube D; + Nyxus::bin_roi_3d (D, r, c.greydepth); + ASSERT_EQ (D.size(), 3u); + EXPECT_EQ (D.zyx (0, 0, 0), c.at_zero); + EXPECT_EQ (D.zyx (0, 0, 1), 0u) << "the background cell"; + EXPECT_EQ (D.zyx (0, 0, 2), c.at_max); + } +} + // The refusal path: a voxel outside the box has no cell in the cube, and is refused rather than // written past it void test_texture_binning_roi_cube_refuses_voxel_outside_box_mechanics() diff --git a/tests/vetting/audit/glcm_3d_golden_regen.md b/tests/vetting/audit/glcm_3d_golden_regen.md index 92c055421..21ec6bca5 100644 --- a/tests/vetting/audit/glcm_3d_golden_regen.md +++ b/tests/vetting/audit/glcm_3d_golden_regen.md @@ -89,8 +89,13 @@ Sanity checks worth running on any regenerated set, both of which the pre-2026-0 ## grey64 table and the retired Wave-9 sweep -`glcm_3d_regression_grey64_ref_vals` (recipe as above but `GLCM_GREYDEPTH=+64`, `matlab_grey_binning`) -was ported verbatim from `glcm_3d_regression_coverage_ref_vals`, formerly in the now-deleted +`glcm_3d_regression_grey64_ref_vals` (recipe `glcm3d.regression_ut_phantom_grey64`: as above but +`GLCM_GREYDEPTH=+64`, `matlab_grey_binning`) holds Nyxus' values at the positive grey depth. The ROI +does not fill its bounding box: its voxels take levels 1..64 and the rest of the box level 0, which +pairs with nothing. `test_3d_glcm_grey64_dump_regression()` prints the table for regeneration, and +`tests/python/test_3d_glcm_analytic.py` holds the rule to the co-occurrence definition. + +The table's 36 features come from `glcm_3d_regression_coverage_ref_vals`, formerly in the now-deleted `test_3d_glcm_coverage.h`. That file ran a generic `TEST_P`-parameterized completeness sweep (internally called "Wave-9") over every 3D family's featureset; it served two purposes that are now split out: diff --git a/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md index fba162041..9bfc7f66d 100644 --- a/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md @@ -216,7 +216,7 @@ values reproduce PyRadiomics **to the last bit** on all seven dependence-axis fe 0.31944444444444442, `DV` 26.743055555555554, `GLN` 48, `GLV` 0), with `3GLDM_DE` at the family's documented `fast_log10` residual and the grey-level features apart only by the level convention. So nothing under the intercept is wrong; the intercept is the whole defect. At *radiomics* binning -`to_grayscale_radiomix()` puts a range of zero width into one bin, so beneath the intercept every voxel +`TextureFeature::fixed_bin_number()` puts a range of zero width into one bin, so beneath the intercept every voxel is level 1 there too; the cell is asserted at no binning, the configuration the bypass was measured at. diff --git a/tests/vetting/audit/glrlm_3d_golden_regen.md b/tests/vetting/audit/glrlm_3d_golden_regen.md index 3b3c7e42b..aa0184e4e 100644 --- a/tests/vetting/audit/glrlm_3d_golden_regen.md +++ b/tests/vetting/audit/glrlm_3d_golden_regen.md @@ -95,7 +95,7 @@ Sanity checks worth running on any regenerated set, both of which the pre-2026-0 ## grey64 table and the retired sweep — `glrlm_3d_regression_grey64_ref_vals` Recipe `glrlm3d.regression_ut_phantom_grey64`: the same segmented phantom at `GLRLM_GREYDEPTH=+64`, -which `bin_intensities_3d()` routes through `matlab_grey_binning` — a fixed 64-level count — instead +which `bin_roi_3d()` (`3d_ooc_volume.h`) routes through `matlab_grey_binning` — a fixed 64-level count — instead of the binCount binning derived from the ROI's own min/max. The ROI does not fill its bounding box, and MATLAB binning sends intensity 0 to level 1, so at this diff --git a/tests/vetting/audit/glszm_3d_golden_regen.md b/tests/vetting/audit/glszm_3d_golden_regen.md index 0598f79d4..6d45ad414 100644 --- a/tests/vetting/audit/glszm_3d_golden_regen.md +++ b/tests/vetting/audit/glszm_3d_golden_regen.md @@ -80,7 +80,7 @@ collide the way two 3D GLCM names do. `nonzero_cells()` does it correctly and the docstring says why. - **`Ns` in the header is the largest zone size (634), not the number of distinct sizes (46).** That is the width Nyxus allocates. -- Nyxus' `to_grayscale_radiomix` and PyRadiomics' `binCount` produce the same partition of the ROI's +- Nyxus' `TextureFeature::fixed_bin_number` and PyRadiomics' `binCount` produce the same partition of the ROI's min..max, so no grey-level correction is needed in either direction. Nothing like 3D NGTDM's zero-min shift applies here. diff --git a/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md index 6bba3677c..0a8c115cd 100644 --- a/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md @@ -272,7 +272,7 @@ that is `SAE = 1/64`, `LAE = 64`, `ZE = 0`, `GLV = 0`, `ZP = 1/8`. Nyxus returns sentinel — `--noval`, default `0.0` — for all sixteen. The guard is unconditional, so it discards every scheme's answer, radiomics binning's included: -`to_grayscale_radiomix` puts a range of zero width into one bin. +`TextureFeature::fixed_bin_number` puts a range of zero width into one bin. Negative control O makes one voxel of the constant block different, so the intercept does not fire, and the family computes `SAE = 0.51020408163265307` on the result — the arithmetic is there, it is the guard that is too wide. diff --git a/tests/vetting/audit/ngtdm_3d_golden_regen.md b/tests/vetting/audit/ngtdm_3d_golden_regen.md index 590751a05..f99b17883 100644 --- a/tests/vetting/audit/ngtdm_3d_golden_regen.md +++ b/tests/vetting/audit/ngtdm_3d_golden_regen.md @@ -88,9 +88,10 @@ apart in their configuration. Recipe `ngtdm3d.regression_ut_phantom`: `bench_ut57_3d`, `GREYDEPTH=64`, `NGTDM_GREYDEPTH=64`, `NGTDM_RADIUS=1`, `IBSI=false`. **Not comparable to the PyRadiomics recipe** — at -`NGTDM_GREYDEPTH=64` the binning is MATLAB-style, which makes bin 1 the background level: a voxel -binned there is not a matrix row of its own but still counts towards its neighbours' neighbourhood -means. These pins claim no oracle. +`NGTDM_GREYDEPTH=64` the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of +the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, +the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts +towards its neighbours' neighbourhood means. These pins claim no oracle. `runAllTests --gtest_filter=*3D_NGTDM_DUMP_PYRADIOMICS*` prints the same for the oracle fixture, alongside each pinned PyRadiomics value — that is the one to run when a residual needs reading diff --git a/tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md b/tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md index f59429858..77f53504c 100644 --- a/tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md +++ b/tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md @@ -317,11 +317,11 @@ At that recipe the old pins turn out to have been roughly right and uselessly im | feature | old pin | Nyxus, `%.17g` | rel. diff | at ±10% | |---|---|---|---|---| -| `3NGTDM_COARSENESS` | 0.00004 | 4.1746559837294642e-05 | 4.2e-2 | passes | -| `3NGTDM_CONTRAST` | 0.66 | 0.63226607482802633 | 4.4e-2 | passes | -| `3NGTDM_BUSYNESS` | 46.0 | 44.389552850401223 | 3.6e-2 | passes | -| `3NGTDM_COMPLEXITY` | 2936.0 | 2819.3512285176689 | 4.1e-2 | passes | -| `3NGTDM_STRENGTH` | 0.024 | 0.024654440905359544 | 2.7e-2 | passes | +| `3NGTDM_COARSENESS` | 0.00004 | 4.1204162221171236e-05 | 2.9e-2 | passes | +| `3NGTDM_CONTRAST` | 0.66 | 0.64067304737766795 | 3.0e-2 | passes | +| `3NGTDM_BUSYNESS` | 46.0 | 45.088896286519478 | 2.0e-2 | passes | +| `3NGTDM_COMPLEXITY` | 2936.0 | 2857.3201047656198 | 2.8e-2 | passes | +| `3NGTDM_STRENGTH` | 0.024 | 0.024330922991243304 | 1.4e-2 | passes | Every one would have passed its own ±10% band, so wiring the file in at the band it carried would have found nothing. They are re-pinned at `%.17g` and the band tightened to `rel=1e-9`; the file diff --git a/tests/vetting/audit/scan_glcm3d_coverage.py b/tests/vetting/audit/scan_glcm3d_coverage.py index 20e8f028b..a7b289a4c 100644 --- a/tests/vetting/audit/scan_glcm3d_coverage.py +++ b/tests/vetting/audit/scan_glcm3d_coverage.py @@ -5,28 +5,83 @@ The mapping is read out of the test sources rather than written by hand, so it cannot drift from the tree. `--check` runs the acceptance checks against `oracle_coverage.csv`. The coverage rule and the checks live in scanlib.py; `report_features.py` joins the scan into `report_output.csv`. This file is -the family's declaration. +the family's declaration, plus the one reading rule that is its own (chained_helper_hits below). """ import os +import re import sys import scanlib +VOLMIN_TEST = os.path.join("python", "test_3d_glcm_pyradiomics.py") +ANALYTIC_TEST = os.path.join("python", "test_3d_glcm_analytic.py") + SOURCES = [ "test_3d_glcm_pyradiomics.h", "test_3d_glcm_regression.h", os.path.join("python", "test_nyxus.py"), + VOLMIN_TEST, + ANALYTIC_TEST, ] +ORACLE_SUFFIX = {"pyradiomics": "pyradiomics", "analytic": "analytic"} + + +def chained_helper_hits(feat_re): + """-> {test function: features} in ANALYTIC_TEST, read through helpers that call helpers. + + Its two cases assert through `_assert_matches_definition()`, which compares against the dict + `_reference()` returns, and only `_reference()` names the features. scanlib credits a case with + the features of the helpers it calls directly; this follows the calls from helper to helper, + so the case is credited with what the chain it runs compares. + """ + with open(os.path.join(scanlib.TESTS, ANALYTIC_TEST), encoding="utf-8", errors="replace") as fh: + text = scanlib.strip_comments(fh.read()) + starts = [m.start() for m in scanlib.TOPLEVEL_DEF.finditer(text)] + [len(text)] + blocks = {re.match(r"def\s+(\w+)", text[a:]).group(1): text[a:b] + for a, b in zip(starts, starts[1:])} + + def reach(name, seen): + feats = set(feat_re.findall(blocks[name])) if name.startswith("_") else set() + for callee in blocks: + if (callee.startswith("_") and callee not in seen + and re.search(r"\b" + re.escape(callee) + r"\s*\(", blocks[name])): + feats |= reach(callee, seen | {callee}) + return feats + + return {name: reach(name, {name}) for name, block in blocks.items() + if name.startswith("test_") and scanlib.ASSERTION.search(block)} + + +def collect(fam, feat_re): + """-> the five coverage maps: scanlib's, with the chained-helper credit of ANALYTIC_TEST added.""" + asserted, oracles, regression, other, where = scanlib.collect(fam, feat_re) + for fn, feats in chained_helper_hits(feat_re).items(): + where[fn] = os.path.basename(ANALYTIC_TEST) + token = ORACLE_SUFFIX.get(fn.rsplit("_", 1)[-1]) + for feat in feats: + if token: + asserted.setdefault(feat, set()).add(fn) + oracles.setdefault(feat, set()).add(token) + else: + other.setdefault(feat, set()).add(fn) + return asserted, oracles, regression, other, where + + FAMILY = scanlib.Family( dim="3D", family="glcm", sources=SOURCES, - oracle_suffix={"pyradiomics": "pyradiomics"}, + oracle_suffix=ORACLE_SUFFIX, + # the volmin case asserts the keys of its dict through a shared helper, so the table is credited + # to the case that loops it; the family's C++ tables need no owner + table_owner={"GLCM_3D_VOLMIN_PYRADIOMICS": "test_3d_glcm_volmin_pyradiomics"}, + table_dialect="python", enum_dim_prefix=True, # the _AVE test aliases the enum (`using F = Nyxus::Feature3D;`), so cover `F::` too enum_alias="GLCM", other_note="asserted", scan_helpers=True, loop_tables=True, + collect_override=collect, ) if __name__ == "__main__": diff --git a/tests/vetting/audit/scan_gldm3d_coverage.py b/tests/vetting/audit/scan_gldm3d_coverage.py index 3a9c88889..e11509c9c 100644 --- a/tests/vetting/audit/scan_gldm3d_coverage.py +++ b/tests/vetting/audit/scan_gldm3d_coverage.py @@ -20,6 +20,10 @@ recipes -- one file, one kind, the same fourteen features at GLDM_GREYDEPTH 64 and 0 -- so without RECIPE_READER the two sets of rows could be swapped and every other check would stay green. + pytest rows test_name holds a gtest case, and a pytest case has none to give. A row of a + recipe in PYTEST_RECIPES leaves it empty and is identified by its recipe + instead: the reader has to resolve to exactly one function, defined in a file + current_test names, that asserts the row's feature at the row's kind. keys vs readers every key of a golden table is resolved to the function its OWN NAME implies, so a missing reader is as loud as a mismatched one. That is how this family shipped 3GLDM_LGLE pinned to 3GLDM_SDE's value, off by a factor of 353, under @@ -36,6 +40,7 @@ "test_3d_gldm_regression.h", "test_3d_gldm_common.h", os.path.join("python", "test_nyxus.py"), + os.path.join("python", "test_3d_gldm_pyradiomics.py"), ] ORACLE_SUFFIX = {"pyradiomics": "pyradiomics"} @@ -44,19 +49,27 @@ PYTEST_ORACLE = {"test_3d_gldm_compatibility": "pyradiomics"} # which file answers which kind of registry row -ORACLE_FILES = {"test_3d_gldm_pyradiomics.h", "test_nyxus.py"} +ORACLE_FILES = {"test_3d_gldm_pyradiomics.h", "test_nyxus.py", "test_3d_gldm_pyradiomics.py"} REGRESSION_FILES = {"test_3d_gldm_regression.h"} +# the volmin case asserts the keys of its dict through a shared helper, so the table is credited to +# the case that loops it +TABLE_OWNER = {"GLDM_3D_VOLMIN_PYRADIOMICS": "test_3d_gldm_volmin_pyradiomics"} + # recipe -> the function that asserts AT that recipe. A row's config_recipe is the configuration its # numbers were taken at, and the function name is where that configuration lives in the tree, so the # two have to agree. RECIPE_READER = { - "gldm3d.pyradiomics_bincount20": re.compile(r"^test_3d_gldm_[a-z0-9]+_pyradiomics$"), + "gldm3d.pyradiomics_bincount20": re.compile(r"^test_3d_gldm_(?!volmin_)[a-z0-9]+_pyradiomics$"), + "gldm3d.pyradiomics_volmin_bincount8": re.compile(r"^test_3d_gldm_volmin_pyradiomics$"), "gldm3d.regression_ut_phantom": re.compile(r"^test_3d_gldm_[a-z0-9]+_regression$"), "gldm3d.regression_ut_phantom_nobinning": re.compile(r"^test_3d_gldm_[a-z0-9]+_nobinning_regression$"), "gldm3d.regression_constant_roi": re.compile(r"^test_3d_gldm_constant_roi_regression$"), } +# the recipes whose assertion is a pytest case, identified by RECIPE_READER rather than by test_name +PYTEST_RECIPES = {"gldm3d.pyradiomics_volmin_bincount8"} + # the scalar tables: the file each lives in, and the suffix its per-feature reader wears. The suffix # is what attributes readers PER TABLE rather than per file -- two tables now share the regression # file, one per config, so a file-wide reader set would report every feature as asserted twice and @@ -193,6 +206,15 @@ def test_name_problems(r, f, st, covering, claimed, cases, where): """ out = [] names = [t.strip() for t in (r.get("test_name") or "").split(";") if t.strip()] + recipe = r["config_recipe"].strip() + if not names and recipe in PYTEST_RECIPES: + # see the module docstring: the recipe identifies a pytest row's assertion + fns = sorted(fn for fn in covering + if RECIPE_READER[recipe].match(fn) and where[fn] in claimed) + if len(fns) != 1: + out.append(f"{f} ({st}): config_recipe {recipe} resolves to {fns or 'no function'} " + f"asserting it at this kind in {sorted(claimed)}; a pytest row needs one") + return out if not names: out.append(f"{f} ({st}): no test_name, so the row identifies no assertion") for name in names: @@ -255,6 +277,8 @@ def disagreements(fam, cov): dim="3D", family="gldm", sources=SOURCES, oracle_suffix=ORACLE_SUFFIX, + table_owner=TABLE_OWNER, + table_dialect="python", notes=NOTE, scan_helpers=True, # a name must not match at the tail of a longer one; see scanlib.feature_re diff --git a/tests/vetting/audit/scan_gldzm3d_coverage.py b/tests/vetting/audit/scan_gldzm3d_coverage.py index ce9a97084..da91b4515 100644 --- a/tests/vetting/audit/scan_gldzm3d_coverage.py +++ b/tests/vetting/audit/scan_gldzm3d_coverage.py @@ -6,7 +6,13 @@ tree. `--check` runs the acceptance checks against `oracle_coverage.csv`. The coverage rule and the checks live in scanlib.py; `report_features.py` joins the scan into `report_output.csv`. This file is the family's declaration. + +A pytest case has no gtest case to name in `test_name`. A row of a recipe in PYTEST_RECIPES leaves it +empty and is identified by its recipe instead: RECIPE_READER has to resolve it to exactly one +function, defined in a file `current_test` names, asserting the row's feature against the row's +oracle. Every other row still needs a `test_name` (pytest_identity_problems below). """ +import os import re import sys @@ -15,9 +21,22 @@ # The family's whole in-tree footprint. test_3d_gldzm_common.h is the shared fixture and asserts no # feature, so it is not scanned. test_3d_coverage_common.h reads both pin tables, but only for their # key sets -- it asserts a count and a has-a-pin property, never a feature value -- so it covers -# nothing per-feature either, matching every other 3D scanner here. +# nothing per-feature either, matching every other 3D scanner here. The pytest file is VOLMIN's. SOURCES = ["test_3d_gldzm_mirp.h", "test_3d_gldzm_regression.h"] +ORACLE_SUFFIX = {"mirp": "mirp"} + +# The volmin table is a Python dict in a pytest file. One declaration reads one table dialect and the +# family's own tables are C++ initialisers, so the pytest file has a declaration of its own and its +# scan joins the family's in collect() below. +VOLMIN = scanlib.Family( + dim="3D", family="gldzm", + sources=[os.path.join("python", "test_3d_gldzm_mirp.py")], + oracle_suffix=ORACLE_SUFFIX, + table_owner={"GLDZM_3D_VOLMIN_MIRP": "test_3d_gldzm_volmin_mirp"}, + table_dialect="python", +) + # Only the two features no tool reaches are named. The other 16 are vetted against MIRP on # bench_compat_gldzm_3d and their measurements live in audit/gldzm_3d_mirp_vetting_report.md; # repeating them here would put a second copy of that table in a generated file. @@ -28,18 +47,56 @@ "in IBSI, so it is a drift guard at every recipe", } -# recipe -> the function that asserts AT that recipe. The family has four config cells and two of +# recipe -> the function that asserts AT that recipe. The family has five config cells and two of # them are asserted against the same oracle on the same fixture, so feature, kind and oracle are # identical between them and only the function name says which cell a row records. RECIPE_READER = { "gldzm3d.mirp_compat_phantom": re.compile( - r"^test_3d_gldzm_[a-z0-9]+_(mirp|compat_regression)$"), + r"^test_3d_gldzm_(?!volmin_)[a-z0-9]+_(mirp|compat_regression)$"), "gldzm3d.mirp_compat_phantom_radiomics": re.compile( r"^test_3d_gldzm_[a-z0-9]+_radiomics_(mirp|regression)$"), "gldzm3d.regression_ut_phantom": re.compile(r"^test_3d_gldzm_[a-z0-9]+_regression$"), "gldzm3d.mirp_fbn20_negdepth": re.compile(r"^test_3d_gldzm_negative_greydepth_mirp$"), + "gldzm3d.mirp_volmin_fbn8": re.compile(r"^test_3d_gldzm_volmin_mirp$"), } +# the recipes whose assertion is a pytest case, identified by RECIPE_READER rather than by test_name +PYTEST_RECIPES = {"gldzm3d.mirp_volmin_fbn8"} + + +def collect(fam, feat_re): + """-> the five coverage maps of the family's sources and of VOLMIN's, joined.""" + maps = scanlib.collect(fam, feat_re) + for into, more in zip(maps, scanlib.collect(VOLMIN, feat_re)): + for key, val in more.items(): + if isinstance(val, set): + into.setdefault(key, set()).update(val) + else: + into[key] = val + return maps + + +def pytest_identity_problems(fam, cov): + """scanlib's missing_test_name, with a pytest row identified by its recipe (module docstring).""" + out = [] + for r in cov.rows: + if r["test_name"].strip(): + continue + f, recipe = r["feature"], r["config_recipe"].strip() + if recipe not in PYTEST_RECIPES: + out.append(f"{f}: no test_name, so current_test names an assertion nothing identifies") + continue + claimed = {t for t in r["current_test"].split(";") if t} + fns = sorted(fn for fn in cov.asserted.get(f, set()) + if RECIPE_READER[recipe].match(fn) and cov.where[fn] in claimed + and scanlib.oracle_token(fam, fn) == r["oracle"].strip()) + if len(fns) != 1: + out.append(f"{f}: config_recipe {recipe} resolves to {fns or 'no function'} asserting " + f"it against {r['oracle'] or 'no oracle'} in {sorted(claimed)}; a pytest row " + f"needs one") + return out + + FAMILY = scanlib.Family( dim="3D", family="gldzm", sources=SOURCES, @@ -47,14 +104,17 @@ # The vetted cell is gldzm3d.mirp_compat_phantom, where neither tool discretises, so what the # comparison measures is the GLDZM rather than the binning the two disagree about on a CT-like # fixture (audit/gldzm_3d_mirp_vetting_report.md). - oracle_suffix={"mirp": "mirp"}, + oracle_suffix=ORACLE_SUFFIX, table_owner={"gldzm_3d_mirp_negdepth_ref_vals": "test_3d_gldzm_negative_greydepth_mirp"}, notes=NOTE, enum_dim_prefix=True, other_note="asserted", loop_tables=True, - checks=scanlib.CORE_CHECKS | scanlib.IDENTITY_CHECKS, + # missing_test_name is pytest_identity_problems, which reads a pytest row by its recipe + checks=scanlib.CORE_CHECKS | (scanlib.IDENTITY_CHECKS - {"missing_test_name"}), + extra_problems=pytest_identity_problems, recipe_reader=RECIPE_READER, + collect_override=collect, ) if __name__ == "__main__": diff --git a/tests/vetting/audit/scan_glrlm3d_coverage.py b/tests/vetting/audit/scan_glrlm3d_coverage.py index 145897c5b..0a4ced2eb 100644 --- a/tests/vetting/audit/scan_glrlm3d_coverage.py +++ b/tests/vetting/audit/scan_glrlm3d_coverage.py @@ -16,6 +16,7 @@ "test_3d_glrlm_pyradiomics.h", "test_3d_glrlm_regression.h", os.path.join("python", "test_nyxus.py"), + os.path.join("python", "test_3d_glrlm_pyradiomics.py"), ] NOTE = { @@ -30,6 +31,10 @@ dim="3D", family="glrlm", sources=SOURCES, oracle_suffix={"pyradiomics": "pyradiomics"}, + # the volmin case asserts the keys of its dict through a shared helper, so the table is credited + # to the case that loops it; the family's C++ tables need no owner + table_owner={"GLRLM_3D_VOLMIN_PYRADIOMICS": "test_3d_glrlm_volmin_pyradiomics"}, + table_dialect="python", notes=NOTE, enum_dim_prefix=True, # the _AVE test aliases the enum (`using F = Nyxus::Feature3D;`), so cover `F::` too diff --git a/tests/vetting/audit/scan_glszm3d_coverage.py b/tests/vetting/audit/scan_glszm3d_coverage.py index a137a536c..75fc80418 100644 --- a/tests/vetting/audit/scan_glszm3d_coverage.py +++ b/tests/vetting/audit/scan_glszm3d_coverage.py @@ -12,6 +12,10 @@ row claims. It also looks the other way, at cases that assert feature values and have no row at all. scanlib's shared checks validate rows that exist; the point of `unregistered_assertions` is the assertion nothing points at. + +A pytest case has no gtest case to name in `test_name`. A row of a recipe in PYTEST_RECIPES leaves it +empty and is identified by its recipe instead: RECIPE_READER has to resolve it to exactly one +function, defined in the one file `current_test` names, asserting the row's feature at the row's kind. """ import os import re @@ -38,20 +42,35 @@ ORACLE_SUFFIX = {"pyradiomics": "pyradiomics"} -# recipe -> the function that asserts AT that recipe. Five recipes read the same sixteen features, +# The volmin table is a Python dict in a pytest file. One declaration reads one table dialect and the +# family's own tables are C++ initialisers, so the pytest file has a declaration of its own and its +# scan joins the family's in collect() below. +VOLMIN = scanlib.Family( + dim="3D", family="glszm", + sources=[os.path.join("python", "test_3d_glszm_pyradiomics.py")], + oracle_suffix=ORACLE_SUFFIX, + table_owner={"GLSZM_3D_VOLMIN_PYRADIOMICS": "test_3d_glszm_volmin_pyradiomics"}, + table_dialect="python", +) + +# recipe -> the function that asserts AT that recipe. Six recipes read the same sixteen features, # three of them out of one file at one kind, so feature, kind and file together still do not say # which configuration a row records -- only the function name does. The feature token is # `[a-z0-9]+` with no underscore, which is what keeps the per-feature sweeps apart from the # whole-family cases: `_regression` is a suffix of `_constant_roi_regression` too. RECIPE_READER = { - "glszm3d.pyradiomics_bincount20": re.compile(r"^test_3d_glszm_[a-z0-9]+_pyradiomics$"), + "glszm3d.pyradiomics_bincount20": re.compile(r"^test_3d_glszm_(?!volmin_)[a-z0-9]+_pyradiomics$"), "glszm3d.pyradiomics_ibsi_gapped": re.compile(r"^test_3d_glszm_ibsi_gapped_pyradiomics$"), + "glszm3d.pyradiomics_volmin_bincount8": re.compile(r"^test_3d_glszm_volmin_pyradiomics$"), "glszm3d.regression_ut_phantom": re.compile(r"^test_3d_glszm_[a-z0-9]+_regression$"), "glszm3d.regression_ut_phantom_nobinning": re.compile(r"^test_3d_glszm_no_binning_regression$"), "glszm3d.regression_constant_roi": re.compile(r"^test_3d_glszm_constant_roi_regression$"), } +# the recipes whose assertion is a pytest case, identified by RECIPE_READER rather than by test_name +PYTEST_RECIPES = {"glszm3d.pyradiomics_volmin_bincount8"} + # `for (auto fc : D3_GLSZM_feature::featureset)` -- a function that range-loops the calculator's own # featureset asserts every feature of the family while naming none of them, so no other pattern sees # it. It is not a table this file could own either: the list comes from the featureset at runtime. @@ -67,6 +86,19 @@ def note(feature, cov): return FAMILY_NOTE +def collect(fam, feat_re): + """-> the five coverage maps of the family's sources and of VOLMIN's, joined.""" + names = {r["feature"] for r in scanlib.registry_rows(fam)} + maps = scanlib.collect(fam, feat_re, names) + for into, more in zip(maps, scanlib.collect(VOLMIN, feat_re)): + for key, val in more.items(): + if isinstance(val, set): + into.setdefault(key, set()).update(val) + else: + into[key] = val + return maps + + def case_to_fn(cov): """-> {gtest case name: (the function it calls, the source file defining that function)}. @@ -146,7 +178,16 @@ def disagreements(fam, cov): # ...and its two identifiers must agree. current_test is the file the case in test_name is # defined in, and ONLY that file: a superset passes a one-way check while still conflating - # this row's assertion with somebody else's. + # this row's assertion with somebody else's. A pytest row's recipe stands in for test_name. + if not name and recipe in PYTEST_RECIPES: + kind_fns = (cov.asserted if r["status"] == "vetted" else cov.regression).get(f, set()) + fns = sorted(fn for fn in kind_fns + if RECIPE_READER[recipe].match(fn) and {cov.where[fn]} == claimed) + if len(fns) != 1: + out.append(f"{f}: config_recipe {recipe} resolves to {fns or 'no function'} " + f"asserting it at this kind in {r['current_test'] or 'empty'}; a pytest " + f"row needs one, in the one file current_test names") + continue if not name: out.append(f"{f}: no test_name, so current_test names an assertion nothing identifies") continue @@ -198,6 +239,7 @@ def disagreements(fam, cov): checks={"unregistered"}, extra_problems=disagreements, recipe_reader=RECIPE_READER, + collect_override=collect, ) if __name__ == "__main__": diff --git a/tests/vetting/audit/scan_ngldm3d_coverage.py b/tests/vetting/audit/scan_ngldm3d_coverage.py index d5723c202..88f241c09 100644 --- a/tests/vetting/audit/scan_ngldm3d_coverage.py +++ b/tests/vetting/audit/scan_ngldm3d_coverage.py @@ -6,8 +6,16 @@ tree. `--check` runs the acceptance checks against `oracle_coverage.csv`. The coverage rule and the checks live in scanlib.py; `report_features.py` joins the scan into `report_output.csv`. This file is the family's declaration. + +A pytest case has no gtest case to name in `test_name`. A row of a recipe in PYTEST_RECIPES leaves it +empty and is identified by its recipe instead: the pattern there has to resolve to exactly one +function, defined in a file `current_test` names, asserting the row's feature against the row's +oracle. Every other row still needs a `test_name` (pytest_identity_problems below). The patterns stay +out of the declaration's `recipe_reader`: the family's gtest recipes declare none, and a partial map +would read every one of them as unreadable. """ import os +import re import sys import scanlib @@ -19,6 +27,22 @@ os.path.join("python", "test_nyxus.py"), ] +ORACLE_SUFFIX = {"mirp": "mirp"} + +# The volmin table is a Python dict in a pytest file. One declaration reads one table dialect and the +# family's own tables are C++ initialisers, so the pytest file has a declaration of its own and its +# scan joins the family's in collect() below. +VOLMIN = scanlib.Family( + dim="3D", family="ngldm", + sources=[os.path.join("python", "test_3d_ngldm_mirp.py")], + oracle_suffix=ORACLE_SUFFIX, + table_owner={"NGLDM_3D_VOLMIN_MIRP": "test_3d_ngldm_volmin_mirp"}, + table_dialect="python", +) + +# recipe -> the pytest function that asserts AT that recipe; see the module docstring +PYTEST_RECIPES = {"ngldm3d.mirp_volmin_fbn8": re.compile(r"^test_3d_ngldm_volmin_mirp$")} + NOTE = { "3NGLDM_DCP": "no oracle row: Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where " "every voxel has a same-level neighbour, so the agreement cannot fail", @@ -26,6 +50,39 @@ "3NGLDM_DCM": "no counterpart in any tool (MIRP's NGLDM emits no dc_mean column)", } +def collect(fam, feat_re): + """-> the five coverage maps of the family's sources and of VOLMIN's, joined.""" + maps = scanlib.collect(fam, feat_re) + for into, more in zip(maps, scanlib.collect(VOLMIN, feat_re)): + for key, val in more.items(): + if isinstance(val, set): + into.setdefault(key, set()).update(val) + else: + into[key] = val + return maps + + +def pytest_identity_problems(fam, cov): + """scanlib's missing_test_name, with a pytest row identified by its recipe (module docstring).""" + out = [] + for r in cov.rows: + if r["test_name"].strip(): + continue + f, recipe = r["feature"], r["config_recipe"].strip() + if recipe not in PYTEST_RECIPES: + out.append(f"{f}: no test_name, so current_test names an assertion nothing identifies") + continue + claimed = {t for t in r["current_test"].split(";") if t} + fns = sorted(fn for fn in cov.asserted.get(f, set()) + if PYTEST_RECIPES[recipe].match(fn) and cov.where[fn] in claimed + and scanlib.oracle_token(fam, fn) == r["oracle"].strip()) + if len(fns) != 1: + out.append(f"{f}: config_recipe {recipe} resolves to {fns or 'no function'} asserting " + f"it against {r['oracle'] or 'no oracle'} in {sorted(claimed)}; a pytest row " + f"needs one") + return out + + FAMILY = scanlib.Family( dim="3D", family="ngldm", sources=SOURCES, @@ -33,14 +90,17 @@ # over one grey-level ladder (oracles/gen_ngldm3d_mirp.py, test_3d_ngldm_mirp.h). 16 of the 19 # features carry a vetted row there; 3NGLDM_DCP is a non-discriminating agreement and # 3NGLDM_GLM / 3NGLDM_DCM have no MIRP counterpart, so those three stay regression-only. - oracle_suffix={"mirp": "mirp"}, + oracle_suffix=ORACLE_SUFFIX, table_owner={"ngldm_3d_mirp_negdepth_ref_vals": "test_3d_ngldm_negative_greydepth_mirp"}, notes=NOTE, enum_dim_prefix=True, enum_alias="NGLDM", other_note="asserted", scan_helpers=True, loop_tables=True, - checks=scanlib.CORE_CHECKS | scanlib.IDENTITY_CHECKS, + # missing_test_name is pytest_identity_problems, which reads a pytest row by its recipe + checks=scanlib.CORE_CHECKS | (scanlib.IDENTITY_CHECKS - {"missing_test_name"}), + extra_problems=pytest_identity_problems, + collect_override=collect, ) if __name__ == "__main__": diff --git a/tests/vetting/benchmarks.md b/tests/vetting/benchmarks.md index 8f78bd189..603d198bc 100644 --- a/tests/vetting/benchmarks.md +++ b/tests/vetting/benchmarks.md @@ -296,6 +296,73 @@ check the dependence axis rather than one number. --- +## `bench_volmin_3d` — a 3D ROI holding the volume's lowest intensity + +| | | +|---|---| +| Files | `tests/data/nifti/phantoms/volmin_inten.nii` + `tests/data/nifti/phantoms/volmin_mask.nii` | +| ROI | label **1**, an ellipsoid of 560 voxels in an 8x12x12 bounding box of 1152 cells, so the box has background in its corners | +| Shape | 8x14x14 int16 voxels at 1x1x1 spacing. ROI voxels at `-1024 + 25 ((3x + 5y + 7z + xyz) mod 17)`, 17 levels over [-1024, -624], 31 of them at -1024; every other voxel at `-600 + ((x + 2y + 3z) mod 50)` | +| Why it exists | its ROI carries the volume's lowest intensity, -1024, and nothing else does. Nyxus stores a volume offset by its lowest intensity, so those ROI voxels are stored as 0, the value the background cells of the bounding box hold. A 3D texture family has to bin them like any other ROI voxel and leave the background out | + +Recipes: `glcm3d.pyradiomics_volmin_bincount8`, `glrlm3d.pyradiomics_volmin_bincount8`, +`gldm3d.pyradiomics_volmin_bincount8`, `glszm3d.pyradiomics_volmin_bincount8`, +`gldzm3d.mirp_volmin_fbn8`, `ngldm3d.mirp_volmin_fbn8`. + +Tests reaching it today: `tests/python/test_3d_{glcm,glrlm,gldm,glszm}_pyradiomics.py` and +`tests/python/test_3d_{gldzm,ngldm}_mirp.py`, each in RAM and out of core (the out-of-core side writes +the same stored intensities as an OME-TIFF Z-stack and streams it at `ram_limit=0`, because the NIfTI +loader delivers a volume in one read). + +**Built by `oracles/volmin_phantom.py`, not by hand.** `--write` writes the three files; a plain run, +and every one of the six generators above, fails if the checked-in files differ from what +`volmin_phantom.build()` produces. The generators load the module from there and read the ROI's own +intensities, so PyRadiomics and MIRP judge the binning rather than inherit it. + +**At 8 bins the bin width is 50**, so every other ROI level sits exactly on a bin edge, and the ROI +populates all eight bins: -1024 and -999 are bin 1, and the top bin holds -674, -649 and the ROI +maximum -624, which the last bin's closed upper edge takes in. + +**Read beside its control.** The pins hold on both; a family that bins a stored 0 to level 0, or +shifts every level by one, misses them here and still meets them on `bench_volmin_ctrl_3d`. + +--- + +## `bench_volmin_ctrl_3d` — the same ROI, its volume's minimum moved outside the box + +| | | +|---|---| +| Files | `tests/data/nifti/phantoms/volmin_ctrl_inten.nii` + `tests/data/nifti/phantoms/volmin_mask.nii` | +| ROI | label **1**, the same 560 voxels at the same intensities as `bench_volmin_3d` | +| Shape | `bench_volmin_3d` with one voxel outside the ROI's bounding box, (z, y, x) = (0, 0, 0), at -2000 | +| Why it exists | the volume's lowest intensity is then not the ROI's, so no ROI voxel is stored as 0 while the ROI's intensities, and with them every oracle value, stay as they are | + +Recipes: the six `bench_volmin_3d` lists. Tests reaching it today: the same six files, each +parametrized over both phantoms. + +**The oracle values are the same on both phantoms, bit for bit**, and each generator checks that on +every run, so one table pins both. That is what makes the pair a control: a difference between the +two Nyxus runs is a difference in how a stored 0 is binned, and nothing else. + +--- + +## `bench_ellipsoid6x40x40_boxbg_3d` — an ellipsoid ROI with background in its box + +| | | +|---|---| +| Data | built inline in `tests/python/test_3d_glcm_analytic.py` (`_ellipsoid()`, `_volume()`), written as an OME-TIFF pair | +| ROI | 2256 voxels of an ellipsoid in a 6x40x40 volume, inside a 6x26x26 bounding box of 4056 cells | +| Shape | intensities `1 + (7x + 13y + 29z) mod 200` on the ROI, 0 elsewhere; none of the ROI's is 0 | +| Why it exists | MATLAB-style binning sends intensity 0 to level 1, the level the ROI's darkest voxels take too, so on a ROI that leaves background in its bounding box only the voxel cloud says which cells are the ROI's. 3D GLCM at the default coarse grey depth is asserted against the co-occurrence definition on it | + +Recipes: `glcm3d.analytic_matlab_background`. + +Tests reaching it today: `tests/python/test_3d_glcm_analytic.py::test_3d_glcm_matlab_background_analytic`. +Its negative case, `test_3d_glcm_matlab_box_analytic`, runs a 4x38x38 box ROI that fills its +bounding box and so holds whether or not the background is counted. + +--- + ## `bench_dsb2018_2d` — four DSB2018 nuclei ROIs | | | diff --git a/tests/vetting/config_recipes.md b/tests/vetting/config_recipes.md index bd22c4885..78cd93942 100644 --- a/tests/vetting/config_recipes.md +++ b/tests/vetting/config_recipes.md @@ -594,6 +594,53 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g - A different binCount from `glcm3d.pyradiomics_bincount20`, so the two benchmarks are not comparable to each other by construction. +## glcm3d.regression_ut_phantom_grey64 +- The same segmented phantom and settings as `glcm3d.regression_ut_phantom` except `GREYDEPTH=64` + and `GLCM_GREYDEPTH=+64` — positive, so `bin_roi_3d` (`3d_ooc_volume.h`) bins through + `matlab_grey_binning`'s fixed 64-level count rather than a bin count over the ROI's own range. + **No oracle** — Nyxus' own values, pinned as drift guards in `glcm_3d_regression_grey64_ref_vals` + (`test_3d_glcm_regression.h`, the `*_grey64_regression` cases) and regenerated by + `test_3d_glcm_grey64_dump_regression()`. +- The ROI does not fill its bounding box. Its voxels take levels 1..64 and the rest of the box level + 0, which pairs with nothing. `glcm3d.analytic_matlab_background` holds that rule to the + co-occurrence definition on a fixture small enough to evaluate it. + +## glcm3d.pyradiomics_volmin_bincount8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: PyRadiomics-style binning, IBSI's fixed bin number + `floor(8 (x - min) / (max - min)) + 1` over the ROI's own range. In RAM, and out of core at + `ram_limit=0` on an OME-TIFF Z-stack holding the same stored intensities. Oracle: `pyradiomics` + 3.0.1 (`binCount: 8`, `label: 1`, `resampledPixelSpacing:` empty, `weightingNorm:` empty, + `force2D: False`) on the ROI's own intensities. Generator: `oracles/gen_glcm3d_pyradiomics.py`. Used + by `tests/python/test_3d_glcm_pyradiomics.py::test_3d_glcm_volmin_pyradiomics`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1. A family that bins a stored 0 to level 0 reads them as background, or shifts + every level by one, and misses the table on `bench_volmin_3d` while it still holds on the control, + whose ROI is stored without a 0. PyRadiomics gives the two the same values, which the generator + checks on every run. +- PyRadiomics reports one value over its 13 directions, the `*_AVE` aggregation; 18 `*_AVE` features + are pinned at `rel=1e-9`. The five logarithmic ones (`DIFENTRO`, `INFOMEAS1`, `INFOMEAS2`, `JE`, + `SUMENTROPY`) carry `fast_log10` and are left out. + +## glcm3d.analytic_matlab_background +- `bench_ellipsoid6x40x40_boxbg_3d`, built in `tests/python/test_3d_glcm_analytic.py`, through the + Python API at the default coarse grey depth, 64: MATLAB-style binning, `floor(64 x / max + 1)` + clipped to `1..64` over the ROI's maximum. In RAM, and out of core at `ram_limit=0`. Oracle: + `analytic`, the co-occurrence definition evaluated in numpy inside the test — for each of the 13 + offsets at distance 1 the ordered pairs of ROI voxels counted by their MATLAB levels, then `ASM` + (`sum p^2`) and `CONTRAST` (`sum (i - j)^2 p`) of each normalised matrix, averaged over the 13. Both + are invariant under transposition, and MATLAB-style binning keeps the matrix asymmetric on both + sides. Used by `test_3d_glcm_matlab_background_analytic`: `3GLCM_ASM_AVE` and `3GLCM_CONTRAST_AVE` + at `rel=1e-9`. +- **What it separates.** MATLAB-style binning sends intensity 0 to level 1, the level the ROI's darkest + voxels take too, so a binned value cannot say which cells of the bounding box are the ROI's. 3D + GLCM takes the ROI from its voxel cloud: background cells hold level 0 and pair with nothing. A + family that reads the background as level 1 counts every ROI-background pair and misses the + reference on the ellipsoid. `test_3d_glcm_matlab_box_analytic`, on a ROI that fills its bounding + box, is the negative case that holds either way. + ## morphology3d.mirp_ibsi - The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at its native 1×1×1 spacing, through `D3_SurfaceFeature` with `IBSI=true`, `GREYDEPTH=128`, `PIXELSIZEUM=100`. @@ -728,7 +775,7 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g ## glrlm3d.regression_ut_phantom_grey64 - The same segmented phantom and Nyxus settings as `glrlm3d.regression_ut_phantom` except - `GLRLM_GREYDEPTH=+64` — positive, so `bin_intensities_3d` (`texture_feature.h`) bins through + `GLRLM_GREYDEPTH=+64` — positive, so `bin_roi_3d` (`3d_ooc_volume.h`) bins through `matlab_grey_binning`'s fixed 64-level count rather than a bin count derived from the ROI's own min/max. **No oracle** — Nyxus' own values, pinned as drift guards in `test_3d_glrlm_regression.h` and regenerated by `test_3d_glrlm_dump_regression()`. @@ -743,6 +790,25 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g for `RE`, the family's only `fast_log10` path), so it is not comparable to `glrlm3d.regression_ut_phantom` — the two bin the same voxels differently by construction. +## glrlm3d.pyradiomics_volmin_bincount8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: PyRadiomics-style binning, IBSI's fixed bin number + `floor(8 (x - min) / (max - min)) + 1` over the ROI's own range. In RAM, and out of core at + `ram_limit=0` on an OME-TIFF Z-stack holding the same stored intensities. Oracle: `pyradiomics` + 3.0.1 (`binCount: 8`, `label: 1`, `resampledPixelSpacing:` empty, `weightingNorm:` empty, + `force2D: False`) on the ROI's own intensities. Generator: `oracles/gen_glrlm3d_pyradiomics.py`. + Used by `tests/python/test_3d_glrlm_pyradiomics.py::test_3d_glrlm_volmin_pyradiomics`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1. A family that bins a stored 0 to level 0 reads them as background, or shifts + every level by one, and misses the table on `bench_volmin_3d` while it still holds on the control, + whose ROI is stored without a 0. PyRadiomics gives the two the same values, which the generator + checks on every run. +- PyRadiomics reports one value over its 13 directions, the `*_AVE` aggregation; 15 `*_AVE` features + are pinned at `rel=1e-9`. `3GLRLM_RE_AVE`, the family's only sum over logarithms, carries + `fast_log10` and is left out. + ## ngldm3d.regression_ut_phantom - The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `GREYDEPTH=64`, `IBSI=false`. **No oracle** — pinned Nyxus output as drift guards in @@ -809,6 +875,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics` holds the family to the other sign: at `GREYDEPTH=0` it reads the raw levels, as `ngldm3d.mirp_ibsi_rawlevels` does. +## ngldm3d.mirp_volmin_fbn8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: IBSI's fixed bin number `floor(8 (x - min) / (max - min)) + 1` over the + ROI's own range. In RAM, and out of core at `ram_limit=0` on an OME-TIFF Z-stack holding the same + stored intensities. Oracle: `mirp` 2.6.0 with `by_slice=False`, distance 1, alpha 0, + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=8`, on the ROI's own + intensities (`volmin_phantom.build()`) — each tool discretises for itself. Generator: + `oracles/gen_ngldm3d_mirp.py` (`--check` re-verifies every pin). Used by + `tests/python/test_3d_ngldm_mirp.py::test_3d_ngldm_volmin_mirp`, at `rel=1e-9`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1 (`ngldm_roi_grey_level`). A family that bins a stored 0 to level 0 and then + lifts every level by one, or drops those voxels, misses the table on `bench_volmin_3d` while it + still holds on the control, whose ROI is stored without a 0. MIRP gives the two the same values, + which the generator checks on every run. +- 16 features are pinned; `3NGLDM_DCP` is left out as at the family's other MIRP recipes. + ## gldzm3d.mirp_compat_phantom - The GLDZM compatibility phantom (`compat_int/compat_int_gldzm_3d.nii` + `compat_seg/compat_seg_gldzm_3d.nii`, label 57) at `IBSI=true`, which switches the family's @@ -831,8 +915,8 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g point: `GREYDEPTH=-8`, `IBSI=false`. Oracle: `mirp` 2.6.0 (`by_slice=False`, `base_discretisation_method="none"`). Generator: `oracles/gen_gldzm3d_mirp.py`. Used by `test_3d_gldzm_mirp.h`. -- **At this bin count the scheme is the identity on the fixture's levels.** - `to_grayscale_radiomix` maps 1..8 over a bin width of 7/8 back onto 1..8, the top level clipping +- **At this bin count the scheme is the identity on the fixture's levels.** IBSI's fixed bin number + (`TextureFeature::fixed_bin_number`) maps 1..8 over a bin width of 7/8 back onto 1..8, the top level clipping into the last bin, so the point computes the GLDZM of the same grey levels the no-binning recipe does and MIRP's goldens for it apply unchanged. - **Asserted feature by feature against the tool at these settings**, not inferred from the @@ -886,6 +970,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g - **The radiomics scheme where it re-bins.** `gldzm3d.mirp_compat_phantom_radiomics` runs the same scheme at a bin count that is the identity on its fixture; here 2001 levels fold into 20. +## gldzm3d.mirp_volmin_fbn8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: IBSI's fixed bin number `floor(8 (x - min) / (max - min)) + 1` over the + ROI's own range. In RAM, and out of core at `ram_limit=0` on an OME-TIFF Z-stack holding the same + stored intensities. Oracle: `mirp` 2.6.0 with `by_slice=False`, + `base_discretisation_method="fixed_bin_number"`, `base_discretisation_n_bins=8`, on the ROI's own + intensities (`volmin_phantom.build()`) — each tool discretises for itself. Generator: + `oracles/gen_gldzm3d_mirp.py` (`--check` re-verifies every pin). Used by + `tests/python/test_3d_gldzm_mirp.py::test_3d_gldzm_volmin_mirp`, all sixteen MIRP-mapped features at + `rel=1e-9`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1, and no level is lifted. A family that bins a stored 0 to level 0 and then lifts + every level by one, or drops those voxels, misses the table on `bench_volmin_3d` while it still + holds on the control, whose ROI is stored without a 0. MIRP gives the two the same values, which the + generator checks on every run. + ## ngtdm3d.pyradiomics_binwidth1 - The 4x4x3 NGTDM phantom (`compat_int/compat_int_ngtdm_3d.nii` + `compat_seg/compat_seg_ngtdm_3d.nii`, label 57) at `GREYDEPTH=100`, `IBSI=false`, @@ -928,10 +1030,12 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `GREYDEPTH=64`, `IBSI=false`, `NGTDM_GREYDEPTH=64`, `NGTDM_RADIUS=1`. **No oracle** — pinned Nyxus output as drift guards in `test_3d_ngtdm_regression.h`, regenerated by `test_3d_ngtdm_dump_regression()`. -- `NGTDM_GREYDEPTH=64` is MATLAB-style binning, which makes bin 1 the background level: a voxel - binned there is not a matrix row of its own but still counts towards its neighbours' neighbourhood - means. That is a different quantity from `ngtdm3d.pyradiomics_binwidth1`, where nothing is - background, which is why this fixture carries no oracle claim. +- `NGTDM_GREYDEPTH=64` is MATLAB-style binning: the ROI's voxels take levels 1..64 and the rest of the + bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the + background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts + towards its neighbours' neighbourhood means. That is a different quantity from + `ngtdm3d.pyradiomics_binwidth1`, where nothing is background, which is why this fixture carries no + oracle claim. - Both recipes state `NGTDM_RADIUS` explicitly rather than leaning on the default. At 0 the neighbourhood is empty and every feature is NaN, so a recipe that leaves the radius to whatever a settings vector happens to hold is not a recipe — which is what the unwired version of @@ -952,7 +1056,7 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g levels. - **The two binning schemes coincide by construction, not by luck.** PyRadiomics' `binCount` lays `binCount` uniform edges over the ROI's own min..max and digitises to 1..N; - `to_grayscale_radiomix` computes `floor(binCount (x - min) / (max - min)) + 1` and clamps the top bin, + `TextureFeature::fixed_bin_number` computes `floor(binCount (x - min) / (max - min)) + 1` and clamps the top bin, which is the same partition. Both sides then gather zones over the full 26-voxel neighbourhood. That is what makes `rel=1e-9` honest on a cross-tool comparison: fifteen of the sixteen features agree to the last bit. @@ -1001,6 +1105,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g `glszm3d.regression_ut_phantom_nobinning` produce bit-identical values AND matrices on this fixture, which is why `matrix/glszm3d.md` carries one cell for the two. +## glszm3d.pyradiomics_volmin_bincount8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: PyRadiomics-style binning, IBSI's fixed bin number + `floor(8 (x - min) / (max - min)) + 1` over the ROI's own range. In RAM, and out of core at + `ram_limit=0` on an OME-TIFF Z-stack holding the same stored intensities. Oracle: `pyradiomics` + 3.0.1 (`binCount: 8`, `label: 1`, `resampledPixelSpacing:` empty, `weightingNorm:` empty, + `force2D: False`) on the ROI's own intensities. Generator: `oracles/gen_glszm3d_pyradiomics.py`. + Used by `tests/python/test_3d_glszm_pyradiomics.py::test_3d_glszm_volmin_pyradiomics`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1. A family that bins a stored 0 to level 0 reads them as background, or shifts + every level by one, and misses the table on `bench_volmin_3d` while it still holds on the control, + whose ROI is stored without a 0. PyRadiomics gives the two the same values, which the generator + checks on every run. +- 15 features are pinned at `rel=1e-9`; `3GLSZM_ZE`, the family's only sum over logarithms, carries + `fast_log10` and is left out. + ## glszm3d.regression_ut_phantom - The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `GREYDEPTH=64`, `IBSI=false` and `GLSZM_GREYDEPTH=64` (positive selects MATLAB-style binning into @@ -1077,6 +1199,24 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g - `3GLDM_DE` is banded separately at `abs=4e-3` for `fast_log10()`; see the registry note and `audit/gldm_3d_pyradiomics_vetting_report.md`. +## gldm3d.pyradiomics_volmin_bincount8 +- `bench_volmin_3d` (`phantoms/volmin_inten.nii` + `phantoms/volmin_mask.nii`, label 1) and its + control `bench_volmin_ctrl_3d` (`phantoms/volmin_ctrl_inten.nii`, same mask), through the Python API + at `coarse_gray_depth=-8`: PyRadiomics-style binning, IBSI's fixed bin number + `floor(8 (x - min) / (max - min)) + 1` over the ROI's own range. In RAM, and out of core at + `ram_limit=0` on an OME-TIFF Z-stack holding the same stored intensities. Oracle: `pyradiomics` + 3.0.1 (`binCount: 8`, `label: 1`, `resampledPixelSpacing:` empty, `weightingNorm:` empty, + `force2D: False`) on the ROI's own intensities. Generator: `oracles/gen_gldm3d_pyradiomics.py`. + Used by `tests/python/test_3d_gldm_pyradiomics.py::test_3d_gldm_volmin_pyradiomics`. +- **What the fixture separates.** Its ROI holds the volume's lowest intensity, so Nyxus stores those + voxels as 0, the value the background cells of the ROI's bounding box hold; under this binning they + are the ROI's bin 1. A family that bins a stored 0 to level 0 reads them as background, or shifts + every level by one, and misses the table on `bench_volmin_3d` while it still holds on the control, + whose ROI is stored without a 0. PyRadiomics gives the two the same values, which the generator + checks on every run. +- 13 features are pinned at `rel=1e-9`; `3GLDM_DE`, the family's only sum over logarithms, carries + `fast_log10` and is left out. + ## gldm3d.regression_ut_phantom - The segmented phantom (`phantoms/ut_inten.nii` + `phantoms/ut_mask57.nii`, label 57) at `GREYDEPTH=64`, `IBSI=false`, `GLDM_GREYDEPTH=64`. **No oracle** - Nyxus' own values, pinned as @@ -1122,8 +1262,9 @@ oracle for the Nyxus-original features); it is not built in this tree, and the g only thing between the ROI and a matrix. - Reachable in production wherever a segmentation lands on a flat region. All fourteen come back as the sentinel (production default `0.0`, i.e. `--noval`) through `calculate()`'s `aux_min == - aux_max` intercept, whose comment says blank ROIs. At radiomics binning `to_grayscale_radiomix()` - puts a range of zero width into one bin, so beneath the intercept every voxel is level 1 there too. + aux_max` intercept, whose comment says blank ROIs. At radiomics binning + `TextureFeature::fixed_bin_number()` puts a range of zero width into one bin, so beneath the + intercept every voxel is level 1 there too. - **PyRadiomics 3.0.1 computes a full GLDM on the same voxels** at `binWidth=1, gldm_a=0, distances=[1]`: `P_gldm` is 1x4, `[8, 20, 16, 4]` over one grey level. Bypassing the intercept as a negative control, Nyxus reproduces it on all seven dependence-axis features to the last bit diff --git a/tests/vetting/matrix/gldm3d.md b/tests/vetting/matrix/gldm3d.md index 50555bab3..7f200e637 100644 --- a/tests/vetting/matrix/gldm3d.md +++ b/tests/vetting/matrix/gldm3d.md @@ -7,9 +7,14 @@ Axes are the settings `D3_GLDM_feature` actually reads, per SPEC §5.2 step 1 auto greyInfo = STNGS_GLDM_GREYDEPTH(s); if (STNGS_IBSI(s)) greyInfo = 0; -bin_intensities_3d (D, r.aux_image_cube, r.aux_min, r.aux_max, greyInfo); +SimpleCube D; +Nyxus::bin_roi_3d (D, r, greyInfo); ``` +`bin_roi_3d` (`3d_ooc_volume.h`) writes each ROI voxel at its grey level and every other cell of the +bounding box at 0. Under both binning schemes every ROI voxel, one stored as 0 included, takes a +level of 1 or more (`TextureFeature::bin_roi_voxel`), so level 0 is the background. + **One and a half axes, not two.** `GLDM_GREYDEPTH` is the family's own binning, and its *sign* selects the scheme rather than its magnitude alone: @@ -39,6 +44,7 @@ There is no GPU axis either: `D3_GLDM_feature::calculate()` has no `STNGS_USEGPU | `GLDM_GREYDEPTH` | `IBSI` | benchmark | verdict | recipe / oracle | |---|---|---|---|---| | `-20` (binCount 20) | false | `bench_compat_liver_3d` | **VALID(pyradiomics)** | `gldm3d.pyradiomics_bincount20`; all 14 features asserted in `test_3d_gldm_pyradiomics.h` at `abs=1e-9`, `3GLDM_DE` at `abs=4e-3` | +| `-8` (binCount 8) | false | `bench_volmin_3d`, `bench_volmin_ctrl_3d` | **VALID(pyradiomics)** | `gldm3d.pyradiomics_volmin_bincount8`; 13 features asserted in `tests/python/test_3d_gldm_pyradiomics.py` at `rel=1e-9`, in RAM and out of core, on a ROI holding the volume's lowest intensity and on its control; `3GLDM_DE` left out for `fast_log10` | | `64` (MATLAB levels) — **the default**, the coarse grey depth | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim | | `0` — no binning | false | `bench_ut57_3d` | **VALID-prod-only** → regression | `gldm3d.regression_ut_phantom_nobinning`; all 14 pinned in `test_3d_gldm_regression.h` at `rel=1e-9`; no oracle claim — see below | | any | true | — | **same cell as the row above** | forced to `greyInfo = 0`, i.e. the same code path, reached a different way; the pins above are what guard it | @@ -139,7 +145,7 @@ under the intercept is wrong. **The intercept is the whole defect**, and what pr is the no-value sentinel — `--noval`, default `0.0` — for all fourteen. **Under every binning scheme the intercept is what answers.** At radiomics binning -`TextureFeature::to_grayscale_radiomix()` puts a range of zero width into one bin, so beneath the +`TextureFeature::fixed_bin_number()` puts a range of zero width into one bin, so beneath the intercept every voxel would be level 1 — the same one-level matrix as at no binning, on a level of its own number. The cell is asserted at `GLDM_GREYDEPTH=0` because that is where the bypass was measured against PyRadiomics. @@ -161,5 +167,5 @@ on a non-integer intensity volume. For `bench_constant_roi_3d`: nothing measured is missing, and nothing needs porting — the seven dependence-axis features already reproduce PyRadiomics to the last bit once the intercept is out of the way. What stands between the cell and VALID is a production change: the `aux_min == aux_max` -intercept has to stop firing for nonempty ROIs, and the zero-range radiomics binning underneath has -to put a constant ROI on one foreground level instead of on background. +intercept has to stop firing for nonempty ROIs. Under both binning schemes the binning underneath +already puts a constant ROI on a single level of 1 or more. diff --git a/tests/vetting/matrix/gldzm3d.md b/tests/vetting/matrix/gldzm3d.md index 6d3eeea86..4955414b9 100644 --- a/tests/vetting/matrix/gldzm3d.md +++ b/tests/vetting/matrix/gldzm3d.md @@ -38,15 +38,15 @@ at every cell even though no tool computes them. |---|---|---|---|---|---| | 1 | **none** — grey level = the voxel's own value | `IBSI=true` (any `GREYDEPTH`), or `GREYDEPTH=0, IBSI=false` | **VALID(mirp)** | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom` | the 16 pinned in `test_3d_gldzm_mirp.h` at an absolute 1e-9, measured residual 5.7e-15; `GLM`/`ZDM` pinned in `test_3d_gldzm_regression.h`. `test_3d_gldzm_no_binning_spellings_agree_mechanics` holds the two spellings to one set of values; `test_3d_gldzm_zero_level_voxels_are_zoned_mechanics` holds the level-0 lift this point needs | | 2 | **MATLAB** — `floor(n·i / ROI max) + 1`, clipped into `[1, n]` | `GREYDEPTH > 0, IBSI=false` | **VALID-BUT-PRODUCTION-ONLY** | 18 `regression` at `gldzm3d.regression_ut_phantom` | all 18 pinned in `test_3d_gldzm_regression.h` at `rel=1e-9` on `bench_ut57_3d`. No tool reproduces this scheme — see "Why point 2 has no oracle" | -| 3 | **radiomics** — IBSI's fixed bin number, `floor(n (i − ROI min) / (max − min)) + 1` | `GREYDEPTH < 0, IBSI=false` | **VALID(mirp)**, at a bin count the scheme maps identically and at one that re-bins | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom_radiomics`; 16 `vetted` at `gldzm3d.mirp_fbn20_negdepth` | the 16 asserted against MIRP **at this cell's own settings** in `test_3d_gldzm_mirp.h`, `GREYDEPTH=-8` on `bench_compat_gldzm_3d`; `GLM`/`ZDM` pinned beside them. `test_3d_gldzm_negative_greydepth_mirp` asserts the 16 again at `GREYDEPTH=-20` on `bench_ut57_3d`, where 2001 levels fold into 20 and MIRP's `fixed_bin_number` bins for itself, worst residual 2.4e-16. `test_3d_gldzm_radiomics_binning_is_identity_here_mechanics` holds the identity that is the *reason* MIRP's goldens transfer — the coverage is the 16 rows, not the equivalence; `test_3d_gldzm_zero_level_voxels_are_zoned_radiomics_mechanics` holds the level-0 lift this point needs, which gathers its levels as a set rather than a ladder and so is its own code path | +| 3 | **radiomics** — IBSI's fixed bin number, `floor(n (i − ROI min) / (max − min)) + 1` | `GREYDEPTH < 0, IBSI=false` | **VALID(mirp)**, at a bin count the scheme maps identically and at one that re-bins | 16 `vetted` + 2 `regression` at `gldzm3d.mirp_compat_phantom_radiomics`; 16 `vetted` at `gldzm3d.mirp_fbn20_negdepth`; 16 `vetted` at `gldzm3d.mirp_volmin_fbn8` | the 16 asserted against MIRP **at this cell's own settings** in `test_3d_gldzm_mirp.h`, `GREYDEPTH=-8` on `bench_compat_gldzm_3d`; `GLM`/`ZDM` pinned beside them. `test_3d_gldzm_negative_greydepth_mirp` asserts the 16 again at `GREYDEPTH=-20` on `bench_ut57_3d`, where 2001 levels fold into 20 and MIRP's `fixed_bin_number` bins for itself, worst residual 2.4e-16. `tests/python/test_3d_gldzm_mirp.py` asserts them at 8 bins on `bench_volmin_3d`, whose ROI holds the volume's lowest intensity and so has voxels stored as 0, and on its control, in RAM and out of core. `test_3d_gldzm_radiomics_binning_is_identity_here_mechanics` holds the identity that is the *reason* MIRP's goldens transfer — the coverage is the 16 rows, not the equivalence; `test_3d_gldzm_zero_level_voxels_are_zoned_radiomics_mechanics` holds that this point lifts no level: a raw 0 in the ROI is bin 1, so the levels it gathers as a set are 1 and 5 | **What point 3 does and does not establish.** At `GREYDEPTH=-8` the scheme is the identity on this -fixture's levels 1..8: `to_grayscale_radiomix` maps them over a bin width of 7/8 back onto +fixture's levels 1..8: IBSI's fixed bin number maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin. So that recipe vets the cell **at that bin count on that fixture**. A bin count that actually re-bins is `gldzm3d.mirp_fbn20_negdepth`: the scheme bins from the ROI minimum, as the tools do, so MIRP's `fixed_bin_number` is config-matched to it with no level reproduction on the MIRP side, and the 16 features agree at 20 bins on the segmented -phantom. +phantom. `gldzm3d.mirp_volmin_fbn8` re-bins too, at 8 bins on a ROI with voxels stored as 0. ## Reference mappings, and the evidence behind the verdicts diff --git a/tests/vetting/matrix/glszm3d.md b/tests/vetting/matrix/glszm3d.md index 8f03b8380..4110baedf 100644 --- a/tests/vetting/matrix/glszm3d.md +++ b/tests/vetting/matrix/glszm3d.md @@ -19,6 +19,7 @@ therefore has no distance, angle or alpha axis at all, unlike 3D GLCM, 3D GLRLM | ibsi | binning | levels | verdict | recipe / oracle | |---|---|---|---|---| | False | radiomics (`GLSZM_GREYDEPTH < 0`) | 20 bins | VALID | `glszm3d.pyradiomics_bincount20` — pyradiomics, 16/16 | +| False | radiomics (`GLSZM_GREYDEPTH < 0`) | 8 bins, on a ROI holding the volume's lowest intensity | VALID | `glszm3d.pyradiomics_volmin_bincount8` — pyradiomics, 15/16 (`3GLSZM_ZE` left out for `fast_log10`), on `bench_volmin_3d` and its control `bench_volmin_ctrl_3d`, in RAM and out of core | | False | MATLAB (`GLSZM_GREYDEPTH > 0`) | 64 | VALID-prod-only | drift guard, `glszm3d.regression_ut_phantom` — no oracle | | False | none (`GLSZM_GREYDEPTH == 0`) | the raw levels | VALID | `glszm3d.pyradiomics_ibsi_gapped` — pyradiomics, 16/16 + the matrix, on `bench_cube3_gapped_levels`; pinned on the phantom too, `glszm3d.regression_ut_phantom_nobinning` | | True | none (forced) | the raw levels | VALID — the same cell | measured identical to the row above, values and matrix, by `test_3d_glszm_ibsi_equals_no_binning_mechanics`; see below | @@ -113,7 +114,7 @@ Nyxus returns the soft-NaN sentinel for all sixteen instead, which is `--noval` external tool reproduces, which is what SPEC §5.1 gives that disposition to, so it earns a regression row rather than a dropped one — and the cell says in full that the behaviour it pins is a defect. Calling it neither vetted nor invalid is the whole point. The guard is unconditional, so it -discards every scheme's answer: at radiomics binning `to_grayscale_radiomix` puts a range of zero width +discards every scheme's answer: at radiomics binning `TextureFeature::fixed_bin_number` puts a range of zero width into one bin, so there too a matrix of one level is what lies beneath it. Whether to narrow it is `src/` work on its own branch — it changes a public feature's output on a reachable input — so this pass pins the current behaviour rather than changing it: `test_3d_glszm_constant_roi_regression` runs diff --git a/tests/vetting/matrix/ngldm3d.md b/tests/vetting/matrix/ngldm3d.md index 6b8b4697d..74b41867b 100644 --- a/tests/vetting/matrix/ngldm3d.md +++ b/tests/vetting/matrix/ngldm3d.md @@ -33,7 +33,7 @@ One row per Nyxus config point, verdict per SPEC §5.1. | 64 | false | **VALID** | `mirp` at recipe `ngldm3d.mirp_samelevels` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-3`. The same point carries the family's three remaining drift guards, `3NGLDM_DCP` / `3NGLDM_GLM` / `3NGLDM_DCM`, on `bench_ut57_3d` at `rel=1e-9` (`ngldm3d.regression_ut_phantom`) — the only three no tool can judge | | any other > 0 | false | **VALID** — same cell | a positive `GREYDEPTH` sets the ladder's height, not its kind. Every positive depth reaches MIRP the way `ngldm3d.mirp_samelevels` does, so it is one cell exercised at the depth the tests pin (64), not a family of cells | | 0 | false | **VALID** — the `IBSI=true` cell | no binning: the raw intensity is the grey level, exactly as at `IBSI=true`. `test_3d_ngldm_zero_greydepth_equals_ibsi_mechanics` holds all nineteen features equal to that run bit for bit, so the cell below covers it | -| < 0 | false | **VALID** | `mirp` at recipe `ngldm3d.mirp_fbn20_negdepth` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-9` (`3NGLDM_DCENT` at `rel=1e-6`), `GREYDEPTH=-20`, worst measured residual 5.1e-16. IBSI's fixed bin number over the ROI's range, which MIRP's `fixed_bin_number` computes for itself, so the binning is compared too | +| < 0 | false | **VALID** | `mirp` at recipe `ngldm3d.mirp_fbn20_negdepth` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-9` (`3NGLDM_DCENT` at `rel=1e-6`), `GREYDEPTH=-20`, worst measured residual 5.1e-16. IBSI's fixed bin number over the ROI's range, which MIRP's `fixed_bin_number` computes for itself, so the binning is compared too. Again at `ngldm3d.mirp_volmin_fbn8` — 16 features `vetted` in `tests/python/test_3d_ngldm_mirp.py` at `rel=1e-9`, 8 bins on `bench_volmin_3d`, whose ROI holds the volume's lowest intensity and so has voxels stored as 0 that are its bin 1, and on its control, in RAM and out of core | | any | true | **VALID** | `mirp` at recipe `ngldm3d.mirp_ibsi_rawlevels` — 16 features `vetted` in `test_3d_ngldm_mirp.h` at `rel=1e-3`, worst measured residual 7.54e-15. `IBSI` keeps the raw level, so this point does not bin: the raw intensity is the grey level (2001 distinct here) and MIRP at `base_discretisation_method="none"` matches by construction. `GREYDEPTH` is not read when `IBSI=true`, which is why the cell spans every depth | `d` and `alpha` add no rows: neither can be varied from settings, so there is no further cross-product diff --git a/tests/vetting/matrix/ngtdm3d.md b/tests/vetting/matrix/ngtdm3d.md index f99810577..535d0d8ca 100644 --- a/tests/vetting/matrix/ngtdm3d.md +++ b/tests/vetting/matrix/ngtdm3d.md @@ -46,9 +46,10 @@ the reason rather than only the settings. ## Why the MATLAB-binning cell carries no oracle -At `NGTDM_GREYDEPTH > 0` the binning is MATLAB-style, and `zeroI` becomes 1: a voxel binned into -level 1 is treated as background — it gets no matrix row of its own, but still counts towards its -neighbours' neighbourhood means. That is a different quantity from anything PyRadiomics or MIRP +At `NGTDM_GREYDEPTH > 0` the binning is MATLAB-style: the ROI's voxels take levels 1..n and the rest +of the bounding box level 0, and since 0 is then among the levels the family lifts every level by +one, the background to 1, and `zeroI` is 1. A background voxel is no centre, but it is a grey level +of the matrix and still counts towards its neighbours' neighbourhood means. That is a different quantity from anything PyRadiomics or MIRP computes (both treat every in-mask voxel as a matrix row), so the cell is production-only and its pins are drift guards. diff --git a/tests/vetting/oracle_coverage.csv b/tests/vetting/oracle_coverage.csv index c56c49bf3..b9f1d3633 100644 --- a/tests/vetting/oracle_coverage.csv +++ b/tests/vetting/oracle_coverage.csv @@ -730,161 +730,210 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3GLCM_SUMENTROPY,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=2e-3,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is 7.6e-4. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only). That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, 3D,3GLCM_SUMVARIANCE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,"pyradiomics/mirp (DIS=DifferenceAverage, HOM1=Id, HOM2=Idm, SUMVAR=ClusterTendency, ENERGY=JointEnergy=ASM, VAR=mirp cm_var); CONFIG-SENSITIVE: symmetric+13dir vs Nyxus asym/1-offset/100lvl",,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is <= 1.2e-15. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only).",, 3D,3GLCM_VARIANCE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,"pyradiomics/mirp (DIS=DifferenceAverage, HOM1=Id, HOM2=Idm, SUMVAR=ClusterTendency, ENERGY=JointEnergy=ASM, VAR=mirp cm_var); CONFIG-SENSITIVE: symmetric+13dir vs Nyxus asym/1-offset/100lvl",,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is <= 1.2e-15. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only).",, -3D,3GLCM_ASM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_ACOR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_CLUPROM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_CLUSHADE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_CLUTEND_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_CONTRAST_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_CORRELATION_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_DIFAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_ASM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_ASM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_ASM_AVE,glcm,vetted,analytic,agreed,glcm3d.analytic_matlab_background,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,,,in-tree,"vetted vs the definition at recipe glcm3d.analytic_matlab_background: MATLAB-style binning at the default coarse grey depth 64 on bench_ellipsoid6x40x40_boxbg_3d, an ellipsoid ROI whose bounding box has background in it, in RAM and out of core. The reference, evaluated in numpy inside the test, counts for each of the 13 offsets at distance 1 the ordered pairs of ROI voxels by their MATLAB levels, floor(64 x / max + 1) clipped to 1..64, and takes ASM (sum p^2) of each normalised matrix, averaged over the 13. A family that reads the bounding box's background as level 1 counts every ROI-background pair and parts from it on the ellipsoid; test_3d_glcm_matlab_box_analytic, a ROI that fills its bounding box, is the negative case that holds either way. Asserted at rel=1e-9 by test_3d_glcm_matlab_background_analytic in tests/python/test_3d_glcm_analytic.py, a pytest case, so test_name is empty.",,bench_ellipsoid6x40x40_boxbg_3d +3D,3GLCM_ACOR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_ACOR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_CLUPROM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_CLUPROM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_CLUSHADE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_CLUSHADE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_CLUTEND_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_CLUTEND_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_CONTRAST_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_CONTRAST_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_CONTRAST_AVE,glcm,vetted,analytic,agreed,glcm3d.analytic_matlab_background,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py;test_3d_glcm_analytic.py,,,,in-tree,"vetted vs the definition at recipe glcm3d.analytic_matlab_background: MATLAB-style binning at the default coarse grey depth 64 on bench_ellipsoid6x40x40_boxbg_3d, an ellipsoid ROI whose bounding box has background in it, in RAM and out of core. The reference, evaluated in numpy inside the test, counts for each of the 13 offsets at distance 1 the ordered pairs of ROI voxels by their MATLAB levels, floor(64 x / max + 1) clipped to 1..64, and takes CONTRAST (sum (i - j)^2 p) of each normalised matrix, averaged over the 13. A family that reads the bounding box's background as level 1 counts every ROI-background pair and parts from it on the ellipsoid; test_3d_glcm_matlab_box_analytic, a ROI that fills its bounding box, is the negative case that holds either way. Asserted at rel=1e-9 by test_3d_glcm_matlab_background_analytic in tests/python/test_3d_glcm_analytic.py, a pytest case, so test_name is empty.",,bench_ellipsoid6x40x40_boxbg_3d +3D,3GLCM_CORRELATION_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_CORRELATION_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_DIFAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_DIFAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLCM_DIFENTRO_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=3e-3,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 1.2e-3. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, -3D,3GLCM_DIFVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_DIFVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_DIFVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLCM_DIS_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, 3D,3GLCM_ENERGY_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, 3D,3GLCM_ENTROPY_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, 3D,3GLCM_HOM1_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_ID_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_IDN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_IDM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_IDMN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_IV_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_JAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_ID_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_ID_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_IDN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_IDN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_IDM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_IDM_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_IDMN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_IDMN_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_IV_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_IV_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_JAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_JAVE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLCM_JE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-3,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 4.1e-4. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, 3D,3GLCM_INFOMEAS1_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=4e-2,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 1.7e-2. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, 3D,3GLCM_INFOMEAS2_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=2e-2,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 7.7e-3. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, 3D,3GLCM_VARIANCE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_JMAX_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_JVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, -3D,3GLCM_SUMAVERAGE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_JMAX_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_JMAX_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_JVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_JVAR_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLCM_SUMAVERAGE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, +3D,3GLCM_SUMAVERAGE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h;test_3d_glcm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLCM_SUMENTROPY_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=2e-3,test_3d_glcm_pyradiomics.h;test_nyxus.py;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 7.6e-4. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference.",, 3D,3GLCM_SUMVARIANCE_AVE,glcm,vetted,pyradiomics,agreed,glcm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glcm_pyradiomics.h;test_3d_glcm_regression.h,,mirp,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15.",, 3D,3GLDM_DE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=4e-3,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. 3GLDM_DE is the exception at abs=4e-3: it is the family's only sum over logarithms and Nyxus takes it through fast_log10(), a float-precision approximation divided by a ten-digit LOG10_2, where PyRadiomics uses numpy.log2. Measured residual 1.7512e-3 absolute / 2.65e-4 relative (Nyxus 6.6031219389041276 against PyRadiomics 6.6048731874541904); the band is that doubled and rounded up to one significant figure. A documented fast path, banded rather than reported. Note the 2D twin's identical calc_DE() measures 1.3e-3 RELATIVE, five times wider, so this figure is this family's own and not carried across. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-6,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band.",TEST_NYXUS.TEST_3D_GLDM_DE_REGRESSION,bench_ut57_3d 3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band.",TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_DN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_DE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_DN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DN_REGRESSION,bench_ut57_3d 3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_DNN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_DN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_DN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_DNN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DNN_REGRESSION,bench_ut57_3d 3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_DV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_DNN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_DNN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_DV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_DV_REGRESSION,bench_ut57_3d 3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_GLN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_DV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_DV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_GLN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_GLN_REGRESSION,bench_ut57_3d 3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_GLV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_GLN,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_GLN,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_GLV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_GLV_REGRESSION,bench_ut57_3d 3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_HGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_GLV,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_GLV,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_HGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_HGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_LDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_HGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_HGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_LDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDE_REGRESSION,bench_ut57_3d 3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_LDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_LDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_LDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_LDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_LDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_LDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_LDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_LDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_LGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_LDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_LDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_LGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. Specific to this feature: the retired table pinned 3GLDM_LGLE at 0.26, byte-identical to the 3GLDM_SDE pin beside it, against a measured 0.00073572128237550161 - a factor of 353 - and test_3d_gldm_lgle_regression() asserted Feature3D::GLDM_SDE under the _lgle_ name, so the feature had no drift guard at all and 3GLDM_SDE had two. Both halves of one paste, in a file nothing ran.",TEST_NYXUS.TEST_3D_GLDM_LGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_SDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_LGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_LGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_SDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDE_REGRESSION,bench_ut57_3d 3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_SDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_SDE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_SDE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_SDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d -3D,3GLDM_SDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,bench_compat_liver_3d +3D,3GLDM_SDHGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_SDHGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLDM_SDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_bincount20,abs=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_REGRESSION,bench_ut57_3d 3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_gldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,bench_ut57_3d -3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_SDLGLE,gldm,regression,,,gldm3d.regression_constant_roi,exact,test_3d_gldm_regression.h,,,,in-tree,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md.",TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,bench_constant_roi_3d +3D,3GLDM_SDLGLE,gldm,vetted,pyradiomics,agreed,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_gldm_pyradiomics.h;test_nyxus.py;test_3d_gldm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,bench_ut57_3d 3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_SDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,bench_ut57_3d 3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_LDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LGLZE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,bench_ut57_3d 3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_LGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_HGLZE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,bench_ut57_3d 3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_HGLZE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDLGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,bench_ut57_3d 3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_SDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_SDHGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,bench_ut57_3d 3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_SDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDLGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,bench_ut57_3d 3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_LDLGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_LDHGLE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,bench_ut57_3d 3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_LDHGLE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNU,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,bench_ut57_3d 3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_GLNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLNUN,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,bench_ut57_3d 3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_GLNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNU,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_ZDNU,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDNUN,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_ZDNUN,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZP,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_ZP,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_REGRESSION,bench_ut57_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.mirp_compat_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_COMPAT_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_GLM,gldzm,regression,,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLM_RADIOMICS_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_GLV,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,bench_ut57_3d 3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_GLV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.mirp_compat_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_COMPAT_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_ZDM,gldzm,regression,,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,test_3d_gldzm_regression.h,,,no-oracle,in-tree,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDM_RADIOMICS_REGRESSION,bench_compat_gldzm_3d 3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDV,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_ZDV,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,bench_compat_gldzm_3d -3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,bench_compat_gldzm_3d +3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,bench_compat_gldzm_3d 3D,3GLDZM_ZDE,gldzm,regression,,,gldzm3d.regression_ut_phantom,rel=1e-9,test_3d_gldzm_regression.h,,,discretisation-mismatch,in-tree,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md",TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,bench_ut57_3d 3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_fbn20_negdepth,rel=1e-6,test_3d_gldzm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3GLDZM_ZDE,gldzm,vetted,mirp,agreed,gldzm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_gldzm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCP,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,non-discriminating-agreement,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would pin the same Nyxus run to a second literal and add no path or config coverage. This one carries no oracle row because Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, at both config points -- an agreement that cannot fail for the reasons an assertion should fail. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCP_REGRESSION,bench_ut57_3d 3D,3NGLDM_GLM,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLM_REGRESSION,bench_ut57_3d 3D,3NGLDM_DCM,ngldm,regression,,,ngldm3d.regression_ut_phantom,rel=1e-9,test_3d_ngldm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCM_REGRESSION,bench_ut57_3d @@ -906,131 +955,162 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_samelevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,scoped-oracle,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,bench_ut57_3d 3D,3NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_LDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_HDE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_LGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_HGLCE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_LDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_LDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_HDLGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_HDHGLE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_GLNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_GLNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_DCNU,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_DCNUN,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_GLV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_DCV,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-6,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_DCENT,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,test_3d_ngldm_mirp.h,test_3d_ngldm_mirp.h,,,in-tree,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md.",TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,bench_ut57_3d 3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,test_3d_ngldm_mirp.h,,,,in-tree,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin.",TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,bench_ut57_3d +3D,3NGLDM_DCENE,ngldm,vetted,mirp,agreed,ngldm3d.mirp_volmin_fbn8,rel=1e-9,test_3d_ngldm_mirp.py,,,,in-tree,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values.",,bench_volmin_3d 3D,3NGTDM_COARSENESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_COARSENESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_R2_PYRADIOMICS,bench_compat_ngtdm_3d -3D,3NGTDM_COARSENESS,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,bench_ut57_3d +3D,3NGTDM_COARSENESS,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,bench_ut57_3d 3D,3NGTDM_CONTRAST,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_CONTRAST,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_R2_PYRADIOMICS,bench_compat_ngtdm_3d -3D,3NGTDM_CONTRAST,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_REGRESSION,bench_ut57_3d +3D,3NGTDM_CONTRAST,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_REGRESSION,bench_ut57_3d 3D,3NGTDM_BUSYNESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_BUSYNESS,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_R2_PYRADIOMICS,bench_compat_ngtdm_3d -3D,3NGTDM_BUSYNESS,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_REGRESSION,bench_ut57_3d +3D,3NGTDM_BUSYNESS,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_REGRESSION,bench_ut57_3d 3D,3NGTDM_COMPLEXITY,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_COMPLEXITY,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_R2_PYRADIOMICS,bench_compat_ngtdm_3d -3D,3NGTDM_COMPLEXITY,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_REGRESSION,bench_ut57_3d +3D,3NGTDM_COMPLEXITY,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_REGRESSION,bench_ut57_3d 3D,3NGTDM_STRENGTH,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,test_3d_ngtdm_pyradiomics.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_PYRADIOMICS,bench_compat_ngtdm_3d 3D,3NGTDM_STRENGTH,ngtdm,vetted,pyradiomics,agreed,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,test_3d_ngtdm_pyradiomics.h,,,,audit,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py",TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_R2_PYRADIOMICS,bench_compat_ngtdm_3d -3D,3NGTDM_STRENGTH,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_REGRESSION,bench_ut57_3d +3D,3NGTDM_STRENGTH,ngtdm,regression,,na,ngtdm3d.regression_ut_phantom,rel=1e-9,test_3d_ngtdm_regression.h,,,,audit,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_REGRESSION,bench_ut57_3d 3D,3GLSZM_SAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SZN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SZN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,bench_ut57_3d -3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SZNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SZNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,bench_ut57_3d -3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZP,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZP,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_GLV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_GLV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,bench_ut57_3d -3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_ZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-3,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_ZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_ZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=2e-3,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_ZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_HGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_HGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,bench_ut57_3d -3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_SAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_SAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d 3D,3GLSZM_LAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py.",TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,bench_compat_liver_3d 3D,3GLSZM_LAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,test_3d_glszm_pyradiomics.h,,,,in-tree,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,bench_cube3_gapped_levels 3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,bench_ut57_3d -3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d -3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant -3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md.",TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,bench_ut57_3d +3D,3GLSZM_SAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_SAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_LAE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LAE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_GLN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_GLN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_GLNN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_GLNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_SZN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_SZN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_SZNN,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_SZNN,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_ZP,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_ZP,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_GLV,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_GLV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_ZV,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_ZV,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_ZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LGLZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_HGLZE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_HGLZE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_SALGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_SALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_SAHGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_SAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_LALGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LALGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLSZM_LAHGLE,glszm,regression,,,glszm3d.regression_constant_roi,abs=1e-9,test_3d_glszm_regression.h,,,,in-tree,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md.",TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,bench_cube2_constant +3D,3GLSZM_LAHGLE,glszm,vetted,pyradiomics,agreed,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glszm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLRLM_SRE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, 3D,3GLRLM_LRE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, 3D,3GLRLM_GLN,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, @@ -1047,22 +1127,37 @@ dim,feature,family,status,oracle,agreement,config_recipe,tolerance,current_test, 3D,3GLRLM_SRHGLE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, 3D,3GLRLM_LRLGLE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, 3D,3GLRLM_LRHGLE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle.",, -3D,3GLRLM_SRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_LRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_GLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_GLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_RLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_RLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_RP_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_GLV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_RV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_SRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_SRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_LRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_LRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_GLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_GLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_GLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_GLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_RLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_RLN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_RLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_RLNN_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_RP_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_RP_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_GLV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_GLV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_RV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_RV_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d 3D,3GLRLM_RE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=2e-3,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 6.2e-4. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle. 3GLRLM_RE is the family's only sum over logarithms and Nyxus evaluates it through fast_log10 (helpers.h), a float-precision log2 approximation, against PyRadiomics' double numpy.log2 - that is the band, not a definitional difference.",, -3D,3GLRLM_LGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_HGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_SRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_SRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_LRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, -3D,3GLRLM_LRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_LGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_LGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_HGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_HGLRE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_SRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_SRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_SRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_SRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_LRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_LRLGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d +3D,3GLRLM_LRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_bincount20,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,audit,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle.",, +3D,3GLRLM_LRHGLE_AVE,glrlm,vetted,pyradiomics,agreed,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,test_3d_glrlm_pyradiomics.h;test_3d_glrlm_regression.h;test_nyxus.py;test_3d_glrlm_pyradiomics.py,,,,in-tree,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values.",,bench_volmin_3d IMQ,FOCUS_SCORE,imq,vetted,opencv,agreed,imq.laplacian_ksize1_zeropad,abs=1e-9,test_imq_opencv.h,,,,audit,"vetted vs OpenCV cv2.Laplacian(roi, CV_64F, ksize=1, BORDER_CONSTANT).var() = 34.956597222222221 (cv2 4.13.0, gen_imq_opencv.py), the Pech-Pacheco et al. (2000) variance-of-the-Laplacian focus measure. The generator asserts cv2's filtered image equals Nyxus' laplacian() cell for cell before comparing any scalar, so the convolution is proved and only the variance step is under test; Nyxus reproduces the scalar to 7.1e-15 absolute (2.0e-16 relative), which is summation order alone. Band is SPEC 7's exact tier, an ABSOLUTE 1e-9 via ASSERT_NEAR. SCOPE: ksize=1, the only kernel calculate() selects. laplacian()'s ksize>1 kernel is cv2.Laplacian's ksize=3 aperture exactly: both stencils are pinned from cv2's unit-spike response in test_imq_opencv.h (TEST_IMQ_FOCUS_SCORE_KERNEL_PER_CALL_OPENCV) and the generator asserts the ksize=3 filtered fixture equal to cv2's cell for cell. The out-of-core path shares the in-RAM scoring code and is held bit-equal to it by test_imq_invariant.h (an invariant, not vetting). Report: audit/imq_opencv_vetting_report.md; matrix/imq.md.",TEST_NYXUS.TEST_IMQ_FOCUS_SCORE_OPENCV,bench_imq_quality_roi IMQ,LOCAL_FOCUS_SCORE,imq,vetted,opencv,agreed,imq.laplacian_ksize1_zeropad,abs=1e-9,test_imq_opencv.h,,,,audit,"vetted vs OpenCV: the mean of cv2.Laplacian(tile, CV_64F, ksize=1, BORDER_CONSTANT).var() over the 2x2 grid of 4x6 tiles get_local_focus_score() cuts the 8x12 fixture into at scale=2 = 28.341145833333336 (cv2 4.13.0, gen_imq_opencv.py, which asserts the tile count and prints each tile's score). Nyxus reproduces it to 7.1e-15 absolute (2.5e-16 relative); band is SPEC 7's exact tier, an ABSOLUTE 1e-9 via ASSERT_NEAR. Negative control: the one-tile value a truncated y < height-M loop bound gives, 7.5763888888888902, is asserted to sit 73% away, so the pin tells the full tiling from the truncated one. Report: audit/imq_opencv_vetting_report.md; matrix/imq.md. ORACLE SPLIT (not_covered.md section E): OpenCV supplies each tile's Laplacian and population variance; the tile grid is Nyxus' own definition, reproduced in the generator and pinned tile by tile by the analytic row.",TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_OPENCV,bench_imq_quality_roi IMQ,LOCAL_FOCUS_SCORE,imq,vetted,analytic,agreed,imq.local_focus_single_spike,abs=0,test_imq_analytic.h,,,,in-tree,"vetted against a closed form, no generator: a single spike of height v clear of the tile edge has a ksize=1 Laplacian of -4v at the spike and +v at its four neighbours, so its tile scores exactly 20v^2/P and every all-zero tile scores 0. test_imq_analytic.h places the spike in each of the scale^2 = 4 tiles in turn on 8x12, 9x12, 8x13 and 9x13 ROIs (a 2x2 grid of 4x6 tiles in all four) and asserts 20*36/24/4 = 7.5 for every placement, and 4x that with a spike in every tile. Exact band: integer arithmetic, exact in double. Both side parities are needed: a y < height-M loop bound stops after the first tile on an even side but reaches the second on an odd one. Which pixels belong to no tile, and the soft-NaN an ROI no tile fits returns, are Nyxus conventions pinned as mechanics in test_imq_mechanics.h, not vetted. See matrix/imq.md.",TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_EACH_TILE_ANALYTIC;TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_ALL_TILES_ANALYTIC, diff --git a/tests/vetting/oracles/gen_glcm3d_pyradiomics.py b/tests/vetting/oracles/gen_glcm3d_pyradiomics.py index f805a7462..3d5816281 100644 --- a/tests/vetting/oracles/gen_glcm3d_pyradiomics.py +++ b/tests/vetting/oracles/gen_glcm3d_pyradiomics.py @@ -1,9 +1,22 @@ -"""OFFLINE PyRadiomics oracle for the 3D GLCM features, on the compat phantom. +"""OFFLINE PyRadiomics oracle for the 3D GLCM features, on the compat phantom and on bench_volmin_3d. python tests/vetting/oracles/gen_glcm3d_pyradiomics.py (from the repository root) -Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_glcm_pyradiomics.h, -exiting non-zero on any mismatch or on any pin it cannot produce. +Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_glcm_pyradiomics.h and +in tests/python/test_3d_glcm_pyradiomics.py, exiting non-zero on any mismatch or on any pin it cannot +produce. + +Recipe `glcm3d.pyradiomics_volmin_bincount8`: bench_volmin_3d (volmin_phantom.py in this directory +builds it and describes it; tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, label 1), +whose ROI holds the volume's lowest intensity, with binCount=8, no resampling, weightingNorm=None, +force2D=False. On the Nyxus side that is coarse_gray_depth=-8. The run also reads the control, +bench_volmin_ctrl_3d (volmin_ctrl_inten.nii, same mask), and fails unless PyRadiomics gives it the +same values bit for bit, which is the fixture's premise: the two volumes differ only outside the ROI's +bounding box. It checks that the three NIfTI files hold what volmin_phantom.build() produces, prints +GLCM_3D_VOLMIN_PYRADIOMICS paste-ready, and verifies that table in both directions at rel 1e-12: every +pin reproduces, and every feature in scope is pinned. The scope is the *_AVE column of every mapped +feature except the five logarithmic ones (DIFENTRO, INFOMEAS1, INFOMEAS2, JE, SUMENTROPY), which carry +Nyxus' fast_log10 approximation and so are left out of a rel 1e-9 table. Recipe `glcm3d.pyradiomics_bincount20`: the compat phantom (tests/data/nifti/compat_int/compat_int_mri.nii + compat_seg/compat_seg_liver.nii, label 1) with @@ -45,6 +58,7 @@ Python <= 3.9); generator=tests/vetting/oracles/gen_glcm3d_pyradiomics.py. Run offline; CI never invokes it. """ +import importlib.util import os import re import sys @@ -60,6 +74,11 @@ INTEN = os.path.join(DATA, "compat_int", "compat_int_mri.nii") MASK = os.path.join(DATA, "compat_seg", "compat_seg_liver.nii") TEST_H = os.path.join(TESTS, "test_3d_glcm_pyradiomics.h") +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_glcm_pyradiomics.py") +VOLMIN_TABLE = "GLCM_3D_VOLMIN_PYRADIOMICS" +VOLMIN_RELTOL = 1e-12 # the pins are PyRadiomics' own output at repr() precision +# the logarithmic features carry Nyxus' fast_log10 approximation and stay out of the volmin table +VOLMIN_LOG = ("3GLCM_DIFENTRO", "3GLCM_INFOMEAS1", "3GLCM_INFOMEAS2", "3GLCM_JE", "3GLCM_SUMENTROPY") RELTOL = 1e-9 # measured residual is <= 1.2e-15 everywhere except the entropy # family, whose per-feature bands live in the test header @@ -218,6 +237,87 @@ def run(): return out +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def volmin_run(vp, inten): + """-> {*_AVE column: PyRadiomics value} on `inten` + bench_volmin_3d's mask, in the table's scope.""" + ex = featureextractor.RadiomicsFeatureExtractor( + binCount=vp.NBINS, label=vp.LABEL, resampledPixelSpacing=None, weightingNorm=None, + force2D=False) + ex.disableAllFeatures() + ex.enableFeatureClassByName("glcm") + res = ex.execute(inten, vp.MASK) + out = {} + for nyx, pyr in PYRAD.items(): + if nyx in VOLMIN_LOG: + continue + key = f"original_glcm_{pyr}" + if key not in res: + raise RuntimeError(f"PyRadiomics produced no {key} on {os.path.basename(inten)}") + out[nyx + "_AVE"] = float(res[key]) + return out + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError(f"table {table} not found in {os.path.basename(path)}") + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return {n: float(v) for n, v in + re.findall(r'"(3GLCM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)} + + +def check_volmin(): + """-> the number of failed checks on recipe glcm3d.pyradiomics_volmin_bincount8.""" + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nbad = vp.check_files() + + got = volmin_run(vp, vp.INTEN) + ctrl = volmin_run(vp, vp.CTRL_INTEN) + print(f"\n# bench_volmin_ctrl_3d gives the same {len(got)} values (the fixture's premise)") + for name in sorted(got): + if ctrl[name] != got[name]: + print(f" FAIL {name}: volmin={got[name]!r} ctrl={ctrl[name]!r}") + nbad += 1 + + print(f"\n# paste-ready {VOLMIN_TABLE}, binCount={vp.NBINS}, label={vp.LABEL} " + f"(left out, logarithmic: {', '.join(n + '_AVE' for n in VOLMIN_LOG)})") + print(f"{VOLMIN_TABLE} = {{") + for name in sorted(got, key=lambda n: n[:-len("_AVE")]): # the test's order: by feature + print(f' "{name}": {got[name]!r},') + print("}") + + pins = parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE) + print(f"\n# verifying the {len(pins)} pins of {VOLMIN_TABLE} against this run, " + f"rel<={VOLMIN_RELTOL:g}, both directions") + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but outside the table's scope") + nbad += 1 + for name in sorted(set(got) - set(pins)): + print(f" UNPINNED {name}: PyRadiomics reports {got[name]!r} and nothing pins it") + nbad += 1 + for name in sorted(set(got) & set(pins)): + rel = abs(got[name] - pins[name]) / max(abs(pins[name]), 1e-300) + if rel > VOLMIN_RELTOL: + print(f" FAIL {name}: pyradiomics={got[name]!r} pinned={pins[name]!r} rel={rel:.3g}") + nbad += 1 + print(" all volmin checks pass" if not nbad else f" {nbad} volmin check(s) failed") + return nbad + + def main(): for p in (INTEN, MASK): if not os.path.exists(p): @@ -275,9 +375,11 @@ def main(): print(f" FAIL {name}: pyradiomics={have!r} pinned={want!r} rel={rel:.3g}") nfail += 1 + nvol = check_volmin() + print(f"\n{nok} verified, {nfail} failed, {nmiss} unproducible, " - f"{nbad} per-direction mismatch(es)") - if nfail or nmiss or nbad: + f"{nbad} per-direction mismatch(es), {nvol} volmin failure(s)") + if nfail or nmiss or nbad or nvol: print("SOME CHECKS FAILED -- do not promote") return 1 print("ALL CHECKS PASSED") diff --git a/tests/vetting/oracles/gen_gldm3d_pyradiomics.py b/tests/vetting/oracles/gen_gldm3d_pyradiomics.py index 5a8a68774..4cf121ca1 100644 --- a/tests/vetting/oracles/gen_gldm3d_pyradiomics.py +++ b/tests/vetting/oracles/gen_gldm3d_pyradiomics.py @@ -1,11 +1,22 @@ -"""OFFLINE PyRadiomics oracle for the 3D GLDM features, on the compat phantom. +"""OFFLINE PyRadiomics oracle for the 3D GLDM features, on the compat phantom and on bench_volmin_3d. python tests/vetting/oracles/gen_gldm3d_pyradiomics.py (from the repository root) Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_gldm_pyradiomics.h -- the fourteen scalars, the dependence matrix of the phantom, and the dependence matrix of the small -hand-worked volume -- exiting non-zero on any mismatch, on any pin it cannot produce, on a bound -violation, or on a cross-table disagreement. +hand-worked volume -- and in tests/python/test_3d_gldm_pyradiomics.py, exiting non-zero on any +mismatch, on any pin it cannot produce, on a bound violation, or on a cross-table disagreement. + +Recipe `gldm3d.pyradiomics_volmin_bincount8`: bench_volmin_3d (volmin_phantom.py in this directory +builds it and describes it; tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, label 1), +whose ROI holds the volume's lowest intensity, with binCount=8, no resampling, weightingNorm=None, +force2D=False. On the Nyxus side that is coarse_gray_depth=-8. The run also reads the control, +bench_volmin_ctrl_3d (volmin_ctrl_inten.nii, same mask), and fails unless PyRadiomics gives it the +same values bit for bit, which is the fixture's premise: the two volumes differ only outside the ROI's +bounding box. It checks that the three NIfTI files hold what volmin_phantom.build() produces, prints +GLDM_3D_VOLMIN_PYRADIOMICS paste-ready, and verifies that table in both directions at rel 1e-12: +every pin reproduces, and every feature in scope is pinned. The scope is every mapped feature except +3GLDM_DE, which carries Nyxus' fast_log10 approximation and so is left out of a rel 1e-9 table. Recipe `gldm3d.pyradiomics_bincount20`: the compat phantom (tests/data/nifti/compat_int/compat_int_mri.nii + compat_seg/compat_seg_liver.nii, label 1) with @@ -53,6 +64,7 @@ actually finds. generator=tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Run offline; CI never invokes it. """ +import importlib.util import math import os import re @@ -68,6 +80,10 @@ INTEN = os.path.join(DATA, "compat_int", "compat_int_mri.nii") MASK = os.path.join(DATA, "compat_seg", "compat_seg_liver.nii") TEST_H = os.path.join(TESTS, "test_3d_gldm_pyradiomics.h") +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_gldm_pyradiomics.py") +VOLMIN_TABLE = "GLDM_3D_VOLMIN_PYRADIOMICS" +# the logarithmic feature carries Nyxus' fast_log10 approximation and stays out of the volmin table +VOLMIN_LOG = ("3GLDM_DE",) # The band this script checks a PINNED DIGIT against a fresh run at, which is not the band the C++ # assertions compare Nyxus against PyRadiomics at. The pins here are PyRadiomics' own output printed @@ -390,6 +406,84 @@ def check_independent(label, pyrad_cells, indep_cells): return bad +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def volmin_run(vp, inten): + """-> {nyxus feature: PyRadiomics value} on `inten` + bench_volmin_3d's mask, in the table's scope.""" + ex = featureextractor.RadiomicsFeatureExtractor( + binCount=vp.NBINS, label=vp.LABEL, resampledPixelSpacing=None, weightingNorm=None, + force2D=False) + ex.disableAllFeatures() + ex.enableFeatureClassByName("gldm") + res = ex.execute(inten, vp.MASK) + out = {} + for nyx, pyr in PYRAD.items(): + if nyx in VOLMIN_LOG: + continue + key = f"original_gldm_{pyr}" + if key not in res: + raise RuntimeError(f"PyRadiomics produced no {key} on {os.path.basename(inten)}") + out[nyx] = float(res[key]) + return out + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError(f"table {table} not found in {os.path.basename(path)}") + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return {n: float(v) for n, v in + re.findall(r'"(3GLDM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)} + + +def check_volmin(): + """-> the number of failed checks on recipe gldm3d.pyradiomics_volmin_bincount8.""" + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nbad = vp.check_files() + + got = volmin_run(vp, vp.INTEN) + ctrl = volmin_run(vp, vp.CTRL_INTEN) + print(f"\n# bench_volmin_ctrl_3d gives the same {len(got)} values (the fixture's premise)") + for name in sorted(got): + if ctrl[name] != got[name]: + print(f" FAIL {name}: volmin={got[name]!r} ctrl={ctrl[name]!r}") + nbad += 1 + + print(f"\n# paste-ready {VOLMIN_TABLE}, binCount={vp.NBINS}, label={vp.LABEL} " + f"(left out, logarithmic: {', '.join(VOLMIN_LOG)})") + print(f"{VOLMIN_TABLE} = {{") + for name in sorted(got): + print(f' "{name}": {got[name]!r},') + print("}") + + pins = parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE) + print(f"\n# verifying the {len(pins)} pins of {VOLMIN_TABLE} against this run, " + f"rel<={PIN_ROUNDTRIP_RELTOL:g}, both directions") + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but outside the table's scope") + nbad += 1 + for name in sorted(set(got) - set(pins)): + print(f" UNPINNED {name}: PyRadiomics reports {got[name]!r} and nothing pins it") + nbad += 1 + for name in sorted(set(got) & set(pins)): + nbad += compare(f"{VOLMIN_TABLE} {name}", got[name], pins[name], PIN_ROUNDTRIP_RELTOL) + print(" all volmin checks pass" if not nbad else f" {nbad} volmin check(s) failed") + return nbad + + def main(): for p in (INTEN, MASK): if not os.path.exists(p): @@ -485,10 +579,13 @@ def main(): else: print(f" OK {cname} = {cval}") + nvol = check_volmin() + print(f"\n{nok} verified, {nfail} failed, {nmiss} unproducible, {len(missing_pin)} unpinned, " f"{nbad} out of range or identity-violating, {ncross} cross-table mismatch(es), " - f"{nindep} definition mismatch(es), {nmat} matrix mismatch(es)") - if nfail or nmiss or nbad or ncross or nindep or nmat or missing_pin: + f"{nindep} definition mismatch(es), {nmat} matrix mismatch(es), " + f"{nvol} volmin failure(s)") + if nfail or nmiss or nbad or ncross or nindep or nmat or missing_pin or nvol: print("SOME CHECKS FAILED -- do not promote") return 1 print("ALL CHECKS PASSED") diff --git a/tests/vetting/oracles/gen_gldzm3d_mirp.py b/tests/vetting/oracles/gen_gldzm3d_mirp.py index d20c33b44..0f77b7824 100644 --- a/tests/vetting/oracles/gen_gldzm3d_mirp.py +++ b/tests/vetting/oracles/gen_gldzm3d_mirp.py @@ -4,7 +4,7 @@ python tests/vetting/oracles/gen_gldzm3d_mirp.py --check (verify only, no tables) python tests/vetting/oracles/gen_gldzm3d_mirp.py --write-phantom (rewrite both fixtures) -Runs MIRP four times and re-verifies everything the tree quotes from it, exiting non-zero on any +Runs MIRP six times and re-verifies everything the tree quotes from it, exiting non-zero on any mismatch, on any quoted feature it cannot produce, and on any feature it produces that nothing quotes. @@ -37,6 +37,17 @@ gldzm_3d_mirp_negdepth_ref_vals in tests/test_3d_gldzm_mirp.h, held at rel 1e-12 -- the pins are printed at full precision, so this is a staleness check, not a vetting band. + 5. `gldzm3d.mirp_volmin_fbn8` -- bench_volmin_3d, whose ROI holds the volume's lowest intensity + (volmin_phantom.py in this directory builds it and describes it; + tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, label 1). MIRP reads the ROI's own + intensities from volmin_phantom.build() as float64, `fixed_bin_number` n=8; on the Nyxus side + that is coarse_gray_depth=-8. The run also reads the control, bench_volmin_ctrl_3d, and fails + unless MIRP gives it the same values bit for bit, which is the fixture's premise: the two + volumes differ only outside the ROI's bounding box. It checks that the three NIfTI files hold + what build() produces, prints GLDZM_3D_VOLMIN_MIRP paste-ready (not under --check), and verifies + that table in tests/python/test_3d_gldzm_mirp.py in both directions at rel 1e-12: every pin + reproduces, and every one of the sixteen features MIRP computes is pinned. + Runs 2 and 3 pin nothing. The artifact they feed is ../audit/gldzm_3d_mirp_vetting_report.md, and that is what this generator checks them against. @@ -67,6 +78,7 @@ `conda create -n nyxus_mirp -c conda-forge python=3.11 mirp numpy scipy`); generator=tests/vetting/oracles/gen_gldzm3d_mirp.py. Run offline; CI never invokes it. """ +import importlib.util import logging import os import re @@ -127,6 +139,9 @@ SUFFIX_FBN = "_3d_fbn_n%d" % NBINS SUFFIX_NEGDEPTH = "_3d_fbn_n%d" % NEGDEPTH_NBINS +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_gldzm_mirp.py") +VOLMIN_TABLE = "GLDZM_3D_VOLMIN_MIRP" + NIFTI_DTYPE = {2: np.uint8, 4: np.int16, 8: np.int32, 16: np.float32, 64: np.float64, 768: np.uint32} @@ -175,15 +190,16 @@ def build_zero_level_phantom(): """-> (intensities, mask), both shaped (z,y,x). A 4x4x4 ROI inside a two-voxel background margin, whose raw intensities are 0 on the voxels with - an even x+y+z and 5 on the rest. Its whole point is the zeros: they are ROI voxels, and the two - binning schemes that do not remap a zero -- IBSI (which bins nothing) and radiomics -- hand them - to the GLDZM as grey level 0, which is not a valid level. It is what separates a family that - lifts them onto a valid level from one that drops them, and MIRP cannot be the judge because it - has the same problem with a level 0 in its input. + an even x+y+z and 5 on the rest. Its whole point is the zeros: they are ROI voxels, and the + binning scheme that does not remap a zero -- IBSI, which bins nothing -- hands them to the GLDZM + as grey level 0, which is not a valid level. It is what separates a family that lifts them onto a + valid level from one that drops them, and MIRP cannot be the judge because it has the same + problem with a level 0 in its input. The radiomics scheme puts them in bin 1 like any other ROI + voxel, so at a bin count of 5 the same fixture has levels 1 and 5 and nothing to lift. Every number it produces is derivable by hand: each parity class is one 26-connected zone (two voxels of one class always touch at least at a corner), every zone reaches the ROI surface so - both sit at distance 1, and the levels after the lift are 1 and 6. + both sit at distance 1, and with no binning the levels after the lift are 1 and 6. """ inten = np.zeros((ZERO_VOL, ZERO_VOL, ZERO_VOL), np.float32) mask = np.zeros((ZERO_VOL, ZERO_VOL, ZERO_VOL), np.uint32) @@ -436,6 +452,61 @@ def verify(got, quoted, what, tol): return nok, nfail, nmiss, unquoted +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError("table %s not found in %s" % (table, os.path.basename(path))) + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return dict((n, float(v)) for n, v in + re.findall(r'"(3GLDZM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)) + + +def check_volmin(features, check): + """-> (n verified, n failed, n unproducible, [unquoted]) for recipe gldzm3d.mirp_volmin_fbn8.""" + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nbad = vp.check_files() + + inten, ctrl_inten, vmask = vp.build() + m32 = (vmask == vp.LABEL).astype(np.int32) + suffix = "_3d_fbn_n%d" % vp.NBINS + got, ctrl = (features(v.astype(np.float64), m32, (1.0, 1.0, 1.0), suffix, + base_discretisation_method="fixed_bin_number", + base_discretisation_n_bins=vp.NBINS) + for v in (inten, ctrl_inten)) + print("\n# bench_volmin_ctrl_3d gives the same %d values (the fixture's premise)" % len(got)) + for name in sorted(got): + if ctrl[name] != got[name]: + print(" FAIL %s: volmin=%r ctrl=%r" % (name, got[name], ctrl[name])) + nbad += 1 + + if not check: + print("\n# gldzm3d.mirp_volmin_fbn8, paste-ready (fixed_bin_number n=%d, label=%d)" + % (vp.NBINS, vp.LABEL)) + print("%s = {" % VOLMIN_TABLE) + for name in sorted(got): + print(' "%s": %r,' % (name, got[name])) + print("}") + + # the table pins all sixteen, so the reverse direction fails the run as well + a, b, c, d = verify(got, parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE), VOLMIN_TABLE, PIN_RELTOL) + return a, b + nbad, c, d + + def main(): write = "--write-phantom" in sys.argv[1:] check = "--check" in sys.argv[1:] @@ -542,6 +613,12 @@ def features(image, mask, spacing, suffix, **discretisation): nmiss += c unquoted += d + a, b, c, d = check_volmin(features, check) + nok += a + nfail += b + nmiss += c + unquoted += d + if not os.path.exists(REPORT): print("\n# %s is missing -- there is nothing the published tables can be checked against, " "which is a failure, not a pass" % os.path.basename(REPORT)) diff --git a/tests/vetting/oracles/gen_glrlm3d_pyradiomics.py b/tests/vetting/oracles/gen_glrlm3d_pyradiomics.py index 65932e2da..760addd6d 100644 --- a/tests/vetting/oracles/gen_glrlm3d_pyradiomics.py +++ b/tests/vetting/oracles/gen_glrlm3d_pyradiomics.py @@ -1,9 +1,22 @@ -"""OFFLINE PyRadiomics oracle for the 3D GLRLM features, on the compat phantom. +"""OFFLINE PyRadiomics oracle for the 3D GLRLM features, on the compat phantom and on bench_volmin_3d. python tests/vetting/oracles/gen_glrlm3d_pyradiomics.py (from the repository root) -Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_glrlm_pyradiomics.h, -exiting non-zero on any mismatch or on any pin it cannot produce. +Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_glrlm_pyradiomics.h and +in tests/python/test_3d_glrlm_pyradiomics.py, exiting non-zero on any mismatch or on any pin it cannot +produce. + +Recipe `glrlm3d.pyradiomics_volmin_bincount8`: bench_volmin_3d (volmin_phantom.py in this directory +builds it and describes it; tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, label 1), +whose ROI holds the volume's lowest intensity, with binCount=8, no resampling, weightingNorm=None, +force2D=False. On the Nyxus side that is coarse_gray_depth=-8. The run also reads the control, +bench_volmin_ctrl_3d (volmin_ctrl_inten.nii, same mask), and fails unless PyRadiomics gives it the +same values bit for bit, which is the fixture's premise: the two volumes differ only outside the ROI's +bounding box. It checks that the three NIfTI files hold what volmin_phantom.build() produces, prints +GLRLM_3D_VOLMIN_PYRADIOMICS paste-ready, and verifies that table in both directions at rel 1e-12: +every pin reproduces, and every feature in scope is pinned. The scope is the *_AVE column of every +mapped feature except 3GLRLM_RE, which carries Nyxus' fast_log10 approximation and so is left out of a +rel 1e-9 table. Recipe `glrlm3d.pyradiomics_bincount20`: the compat phantom (tests/data/nifti/compat_int/compat_int_mri.nii + compat_seg/compat_seg_liver.nii, label 1) with @@ -54,6 +67,7 @@ Python <= 3.9); generator=tests/vetting/oracles/gen_glrlm3d_pyradiomics.py. Run offline; CI never invokes it. """ +import importlib.util import os import re import sys @@ -69,6 +83,11 @@ INTEN = os.path.join(DATA, "compat_int", "compat_int_mri.nii") MASK = os.path.join(DATA, "compat_seg", "compat_seg_liver.nii") TEST_H = os.path.join(TESTS, "test_3d_glrlm_pyradiomics.h") +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_glrlm_pyradiomics.py") +VOLMIN_TABLE = "GLRLM_3D_VOLMIN_PYRADIOMICS" +VOLMIN_RELTOL = 1e-12 # the pins are PyRadiomics' own output at repr() precision +# the logarithmic feature carries Nyxus' fast_log10 approximation and stays out of the volmin table +VOLMIN_LOG = ("3GLRLM_RE",) RELTOL = 1e-1 # matches the C++ assertions (agrees_gt frac_tolerance = 10) LABEL = 1 @@ -235,6 +254,87 @@ def check_bounds(got): return bad +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def volmin_run(vp, inten): + """-> {*_AVE column: PyRadiomics value} on `inten` + bench_volmin_3d's mask, in the table's scope.""" + ex = featureextractor.RadiomicsFeatureExtractor( + binCount=vp.NBINS, label=vp.LABEL, resampledPixelSpacing=None, weightingNorm=None, + force2D=False) + ex.disableAllFeatures() + ex.enableFeatureClassByName("glrlm") + res = ex.execute(inten, vp.MASK) + out = {} + for nyx, pyr in PYRAD.items(): + if nyx in VOLMIN_LOG: + continue + key = f"original_glrlm_{pyr}" + if key not in res: + raise RuntimeError(f"PyRadiomics produced no {key} on {os.path.basename(inten)}") + out[nyx + "_AVE"] = float(res[key]) + return out + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError(f"table {table} not found in {os.path.basename(path)}") + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return {n: float(v) for n, v in + re.findall(r'"(3GLRLM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)} + + +def check_volmin(): + """-> the number of failed checks on recipe glrlm3d.pyradiomics_volmin_bincount8.""" + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nbad = vp.check_files() + + got = volmin_run(vp, vp.INTEN) + ctrl = volmin_run(vp, vp.CTRL_INTEN) + print(f"\n# bench_volmin_ctrl_3d gives the same {len(got)} values (the fixture's premise)") + for name in sorted(got): + if ctrl[name] != got[name]: + print(f" FAIL {name}: volmin={got[name]!r} ctrl={ctrl[name]!r}") + nbad += 1 + + print(f"\n# paste-ready {VOLMIN_TABLE}, binCount={vp.NBINS}, label={vp.LABEL} " + f"(left out, logarithmic: {', '.join(n + '_AVE' for n in VOLMIN_LOG)})") + print(f"{VOLMIN_TABLE} = {{") + for name in sorted(got, key=lambda n: n[:-len("_AVE")]): # the test's order: by feature + print(f' "{name}": {got[name]!r},') + print("}") + + pins = parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE) + print(f"\n# verifying the {len(pins)} pins of {VOLMIN_TABLE} against this run, " + f"rel<={VOLMIN_RELTOL:g}, both directions") + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but outside the table's scope") + nbad += 1 + for name in sorted(set(got) - set(pins)): + print(f" UNPINNED {name}: PyRadiomics reports {got[name]!r} and nothing pins it") + nbad += 1 + for name in sorted(set(got) & set(pins)): + rel = abs(got[name] - pins[name]) / max(abs(pins[name]), 1e-300) + if rel > VOLMIN_RELTOL: + print(f" FAIL {name}: pyradiomics={got[name]!r} pinned={pins[name]!r} rel={rel:.3g}") + nbad += 1 + print(" all volmin checks pass" if not nbad else f" {nbad} volmin check(s) failed") + return nbad + + def main(): for p in (INTEN, MASK): if not os.path.exists(p): @@ -301,9 +401,11 @@ def main(): for name in missing_pin: print(f" UNPINNED {name}: PyRadiomics reports {got[name]!r} and nothing pins it") + nvol = check_volmin() + print(f"\n{nok} verified, {nfail} failed, {nmiss} unproducible, {len(missing_pin)} unpinned, " - f"{nbad} out of range, {nang} per-direction mismatch(es)") - if nfail or nmiss or nbad or nang: + f"{nbad} out of range, {nang} per-direction mismatch(es), {nvol} volmin failure(s)") + if nfail or nmiss or nbad or nang or nvol: print("SOME CHECKS FAILED -- do not promote") return 1 print("ALL CHECKS PASSED") diff --git a/tests/vetting/oracles/gen_glszm3d_pyradiomics.py b/tests/vetting/oracles/gen_glszm3d_pyradiomics.py index d0c84ca74..4ef9a5037 100644 --- a/tests/vetting/oracles/gen_glszm3d_pyradiomics.py +++ b/tests/vetting/oracles/gen_glszm3d_pyradiomics.py @@ -1,18 +1,30 @@ -"""OFFLINE PyRadiomics oracle for the 3D GLSZM features, on the compat phantom. +"""OFFLINE PyRadiomics oracle for the 3D GLSZM features, on the compat phantom and on bench_volmin_3d. python tests/vetting/oracles/gen_glszm3d_pyradiomics.py (from the repository root) Prints the paste-ready goldens AND re-verifies every golden pinned in test_3d_glszm_pyradiomics.h -- the sixteen scalars, the size-zone matrix of the phantom, and the size-zone matrix of the small -hand-worked volume -- exiting non-zero on any mismatch, on any pin it cannot produce, on a bound -violation, or on a cross-table disagreement. +hand-worked volume -- and in tests/python/test_3d_glszm_pyradiomics.py, exiting non-zero on any +mismatch, on any pin it cannot produce, on a bound violation, or on a cross-table disagreement. -TWO RECIPES. `glszm3d.pyradiomics_bincount20` is the phantom run below. `glszm3d.pyradiomics_ibsi_gapped` +THREE RECIPES. `glszm3d.pyradiomics_bincount20` is the phantom run below. `glszm3d.pyradiomics_ibsi_gapped` is the second: a 3x3x3 literal carrying grey levels 1, 3 and 5, read at binWidth=1, which is the only place either side is asked what an absent grey level does to the row index. Nyxus reaches that point through IBSI=true, where calculate() forces its binning to 0; PyRadiomics reaches it through a bin width that leaves the levels alone. Both report Ng = 5 for three occupied levels. +`glszm3d.pyradiomics_volmin_bincount8` is the third: bench_volmin_3d (volmin_phantom.py in this +directory builds it and describes it; tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, +label 1), whose ROI holds the volume's lowest intensity, with binCount=8, no resampling, +weightingNorm=None, force2D=False. On the Nyxus side that is coarse_gray_depth=-8. The run also reads +the control, bench_volmin_ctrl_3d (volmin_ctrl_inten.nii, same mask), and fails unless PyRadiomics +gives it the same values bit for bit, which is the fixture's premise: the two volumes differ only +outside the ROI's bounding box. It checks that the three NIfTI files hold what volmin_phantom.build() +produces, prints GLSZM_3D_VOLMIN_PYRADIOMICS paste-ready, and verifies that table in both directions at +rel 1e-12: every pin reproduces, and every feature in scope is pinned. The scope is every mapped +feature except 3GLSZM_ZE, which carries Nyxus' fast_log10 approximation and so is left out of a rel +1e-9 table. + Recipe `glszm3d.pyradiomics_bincount20`: the compat phantom (tests/data/nifti/compat_int/compat_int_mri.nii + compat_seg/compat_seg_liver.nii, label 1) with binCount=20, no resampling, weightingNorm=None, imageType=Original -- the settings the test header's @@ -43,6 +55,7 @@ Python <= 3.9); generator=tests/vetting/oracles/gen_glszm3d_pyradiomics.py. Run offline; CI never invokes it. """ +import importlib.util import math import os import re @@ -58,6 +71,11 @@ INTEN = os.path.join(DATA, "compat_int", "compat_int_mri.nii") MASK = os.path.join(DATA, "compat_seg", "compat_seg_liver.nii") TEST_H = os.path.join(TESTS, "test_3d_glszm_pyradiomics.h") +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_glszm_pyradiomics.py") +VOLMIN_TABLE = "GLSZM_3D_VOLMIN_PYRADIOMICS" +VOLMIN_RELTOL = 1e-12 # the pins are PyRadiomics' own output at repr() precision +# the logarithmic feature carries Nyxus' fast_log10 approximation and stays out of the volmin table +VOLMIN_LOG = ("3GLSZM_ZE",) RELTOL = 1e-9 # matches the C++ assertions (agrees_gt frac_tolerance = 1e9) ZE_RELTOL = 1e-3 # the band the C++ assertions give 3GLSZM_ZE alone (Nyxus' fast_log10) @@ -339,6 +357,84 @@ def check_identities(got, Nz): return bad +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def volmin_run(vp, inten): + """-> {nyxus feature: PyRadiomics value} on `inten` + bench_volmin_3d's mask, in the table's scope.""" + ex = featureextractor.RadiomicsFeatureExtractor( + binCount=vp.NBINS, label=vp.LABEL, resampledPixelSpacing=None, weightingNorm=None, + force2D=False) + ex.disableAllFeatures() + ex.enableFeatureClassByName("glszm") + res = ex.execute(inten, vp.MASK) + out = {} + for nyx, pyr in PYRAD.items(): + if nyx in VOLMIN_LOG: + continue + key = f"original_glszm_{pyr}" + if key not in res: + raise RuntimeError(f"PyRadiomics produced no {key} on {os.path.basename(inten)}") + out[nyx] = float(res[key]) + return out + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError(f"table {table} not found in {os.path.basename(path)}") + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return {n: float(v) for n, v in + re.findall(r'"(3GLSZM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)} + + +def check_volmin(): + """-> the number of failed checks on recipe glszm3d.pyradiomics_volmin_bincount8.""" + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nbad = vp.check_files() + + got = volmin_run(vp, vp.INTEN) + ctrl = volmin_run(vp, vp.CTRL_INTEN) + print(f"\n# bench_volmin_ctrl_3d gives the same {len(got)} values (the fixture's premise)") + for name in sorted(got): + if ctrl[name] != got[name]: + print(f" FAIL {name}: volmin={got[name]!r} ctrl={ctrl[name]!r}") + nbad += 1 + + print(f"\n# paste-ready {VOLMIN_TABLE}, binCount={vp.NBINS}, label={vp.LABEL} " + f"(left out, logarithmic: {', '.join(VOLMIN_LOG)})") + print(f"{VOLMIN_TABLE} = {{") + for name in sorted(got): + print(f' "{name}": {got[name]!r},') + print("}") + + pins = parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE) + print(f"\n# verifying the {len(pins)} pins of {VOLMIN_TABLE} against this run, " + f"rel<={VOLMIN_RELTOL:g}, both directions") + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but outside the table's scope") + nbad += 1 + for name in sorted(set(got) - set(pins)): + print(f" UNPINNED {name}: PyRadiomics reports {got[name]!r} and nothing pins it") + nbad += 1 + for name in sorted(set(got) & set(pins)): + nbad += compare(f"{VOLMIN_TABLE} {name}", got[name], pins[name], VOLMIN_RELTOL) + print(" all volmin checks pass" if not nbad else f" {nbad} volmin check(s) failed") + return nbad + + def main(): for p in (INTEN, MASK): if not os.path.exists(p): @@ -451,10 +547,12 @@ def main(): else: print(f" OK {cname} = {cval}") + nvol = check_volmin() + print(f"\n{nok} verified, {nfail} failed, {nmiss} unproducible, {len(missing_pin)} unpinned, " f"{nbad} out of range or identity-violating, {ncross} cross-table mismatch(es), " - f"{nmat} matrix mismatch(es)") - if nfail or nmiss or nbad or ncross or nmat or missing_pin: + f"{nmat} matrix mismatch(es), {nvol} volmin failure(s)") + if nfail or nmiss or nbad or ncross or nmat or missing_pin or nvol: print("SOME CHECKS FAILED -- do not promote") return 1 print("ALL CHECKS PASSED") diff --git a/tests/vetting/oracles/gen_ngldm3d_mirp.py b/tests/vetting/oracles/gen_ngldm3d_mirp.py index fc2a88c92..bcea16c20 100644 --- a/tests/vetting/oracles/gen_ngldm3d_mirp.py +++ b/tests/vetting/oracles/gen_ngldm3d_mirp.py @@ -3,9 +3,10 @@ python tests/vetting/oracles/gen_ngldm3d_mirp.py (from the repository root) python tests/vetting/oracles/gen_ngldm3d_mirp.py --check (verify only, no paste-ready tables) -Runs MIRP four times and re-verifies the three comparison tables in the vetting report and every -MIRP golden pinned in test_3d_ngldm_mirp.h, exiting non-zero on any mismatch, on any quoted feature -it cannot produce, and on any feature it produces that the report does not quote. +Runs MIRP six times and re-verifies the three comparison tables in the vetting report, every MIRP +golden pinned in test_3d_ngldm_mirp.h and the volmin table of tests/python/test_3d_ngldm_mirp.py, +exiting non-zero on any mismatch, on any quoted feature it cannot produce, and on any feature it +produces that the report does not quote. - `ngldm3d.mirp_fbn64` -- MIRP discretises the ROI itself, `fixed_bin_number` n=64. The two sides land on different grey levels (below), so this table measures the discretisation gap. @@ -45,11 +46,22 @@ the fixture that separates the two formulas. The pins are printed at full precision, so they are held at rel 1e-12 -- a staleness check, not a vetting band. +`ngldm3d.mirp_volmin_fbn8`, table NGLDM_3D_VOLMIN_MIRP in tests/python/test_3d_ngldm_mirp.py: +bench_volmin_3d, whose ROI holds the volume's lowest intensity (volmin_phantom.py in this directory +builds it and describes it; tests/data/nifti/phantoms/volmin_inten.nii + volmin_mask.nii, label 1). +MIRP reads the ROI's own intensities from volmin_phantom.build() as float64 at 1x1x1 spacing, +`fixed_bin_number` n=8; on the Nyxus side that is coarse_gray_depth=-8. The run also reads the +control, bench_volmin_ctrl_3d, and fails unless MIRP gives it the same values bit for bit, which is +the fixture's premise: the two volumes differ only outside the ROI's bounding box. It checks that the +three NIfTI files hold what build() produces, prints the table paste-ready (not under --check), and +verifies it in both directions at rel 1e-12: every pin reproduces, and every feature MIRP computes +except 3NGLDM_DCP is pinned. + 3NGLDM_GLM (grey level mean) and 3NGLDM_DCM (dependence count mean) have no MIRP counterpart -- its NGLDM emits no gl_mean / dc_mean column -- so they cannot be vetted here at all. 3NGLDM_DCP is computed by both and deliberately not pinned: Nyxus hard-codes it to 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, so the check below allows exactly that one -omission and fails on any other; the negdepth table leaves it out for the same reason. +omission and fails on any other; the negdepth and volmin tables leave it out for the same reason. NIFTI READING WITHOUT A NIFTI LIBRARY: the mirp env has neither SimpleITK nor nibabel. The phantoms are uncompressed single-file NIfTI-1 (magic "n+1"), so the header is parsed directly below and the @@ -62,6 +74,7 @@ generator=tests/vetting/oracles/gen_ngldm3d_mirp.py. Run offline; CI never invokes it. """ import argparse +import importlib.util import logging import os import re @@ -117,6 +130,10 @@ SUFFIX_NEGDEPTH = f"_d1_a0.0_3d_fbn_n{NEGDEPTH_NBINS}" NEGDEPTH_SCOPE = [k for k in MIRP if k != "3NGLDM_DCP"] +VOLMIN_TEST = os.path.join(TESTS, "python", "test_3d_ngldm_mirp.py") +VOLMIN_TABLE = "NGLDM_3D_VOLMIN_MIRP" +VOLMIN_RELTOL = 1e-12 # the pins are MIRP's own output at repr() precision + NIFTI_DTYPE = {2: np.uint8, 4: np.int16, 8: np.int32, 16: np.float32, 64: np.float64} @@ -257,6 +274,91 @@ def features(image, suffix, **discretisation): return (fbn, same, ibsi, neg), span +def _helper(name): + """A shared fixture module from this directory, loaded by path.""" + spec = importlib.util.spec_from_file_location(name, os.path.join(HERE, name + ".py")) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +def parse_py_pins(path, table): + """-> {feature: value} out of a `TABLE = {...}` dict literal in a Python test, braces counted.""" + txt = open(path, encoding="utf-8", errors="replace").read() + m = re.search(r"^" + re.escape(table) + r"\s*=\s*\{", txt, re.M) + if not m: + raise RuntimeError(f"table {table} not found in {os.path.basename(path)}") + depth, i = 1, m.end() + while depth: + depth += {"{": 1, "}": -1}.get(txt[i], 0) + i += 1 + body = re.sub(r"#[^\n]*", "", txt[m.end():i - 1]) # a commented-out golden is not a pin + return {n: float(v) for n, v in + re.findall(r'"(3NGLDM_[A-Z0-9_]+)"\s*:\s*([-0-9.eE+]+)', body)} + + +def check_volmin(check): + """-> (n verified, n failed) for recipe ngldm3d.mirp_volmin_fbn8.""" + import mirp + vp = _helper("volmin_phantom") + print("\n# bench_volmin_3d: the checked-in NIfTI files against volmin_phantom.build()") + nfail = vp.check_files() + + inten, ctrl_inten, vmask = vp.build() + m32 = (vmask == vp.LABEL).astype(np.int32) + suffix = f"_d1_a0.0_3d_fbn_n{vp.NBINS}" + + def features(image): + res = mirp.extract_features( + image=image.astype(np.float64), mask=m32, image_spacing=(1.0, 1.0, 1.0), + by_slice=False, base_feature_families="ngldm", + base_discretisation_method="fixed_bin_number", base_discretisation_n_bins=vp.NBINS) + df = res[0] if isinstance(res, list) else res + out = {} + for nyx in NEGDEPTH_SCOPE: # every mapped feature except 3NGLDM_DCP + col = MIRP[nyx] + suffix + if col not in df.columns: + raise RuntimeError(f"MIRP produced no {col} (for {nyx}) on bench_volmin_3d") + out[nyx] = float(df.iloc[0][col]) + return out + + got, ctrl = features(inten), features(ctrl_inten) + print(f"\n# bench_volmin_ctrl_3d gives the same {len(got)} values (the fixture's premise)") + for name in sorted(got): + if ctrl[name] != got[name]: + print(f" FAIL {name}: volmin={got[name]!r} ctrl={ctrl[name]!r}") + nfail += 1 + + if not check: + print(f"\n# ngldm3d.mirp_volmin_fbn8, paste-ready (fixed_bin_number n={vp.NBINS}, " + f"label={vp.LABEL}; 3NGLDM_DCP left out)") + print(f"{VOLMIN_TABLE} = {{") + for name in sorted(got): + print(f' "{name}": {got[name]!r},') + print("}") + + pins = parse_py_pins(VOLMIN_TEST, VOLMIN_TABLE) + print(f"\n# verifying the {len(pins)} goldens pinned in {VOLMIN_TABLE} against this run, " + f"at rel<={VOLMIN_RELTOL:g}, both directions") + nok = 0 + for name in sorted(set(pins) - set(got)): + print(f" MISSING {name}: pinned {pins[name]!r} but is outside this table's scope") + nfail += 1 + for name in sorted(set(got) - set(pins)): + print(f" FAIL {name}: MIRP computes it in this table's scope and {VOLMIN_TABLE} does " + f"not pin it") + nfail += 1 + for name in sorted(set(pins) & set(got)): + rel = abs(pins[name] - got[name]) / max(abs(got[name]), 1e-300) + if rel <= VOLMIN_RELTOL: + print(f" OK {name}: pin={pins[name]!r} mirp={got[name]!r} rel={rel:.3g}") + nok += 1 + else: + print(f" FAIL {name}: pin={pins[name]!r} mirp={got[name]!r} rel={rel:.3g}") + nfail += 1 + return nok, nfail + + def verify(got, heading, txt, pins, derived, bound): """-> (n verified, n failed, n unproducible, [unquoted]) for one of the report's tables. @@ -431,6 +533,10 @@ def main(): print(f" FAIL {name}: pin={neg_pins[name]!r} mirp={neg[name]!r} rel={rel:.3g}") nfail += 1 + a, b = check_volmin(args.check) + nok += a + nfail += b + # the grey-level span is the report's explanation of the fbn64 gap, so it is checked too span_txt = f"{span[0]}-{span[1]}, {span[2]} distinct" if span_txt not in txt: diff --git a/tests/vetting/oracles/volmin_phantom.py b/tests/vetting/oracles/volmin_phantom.py new file mode 100644 index 000000000..6e1162e6e --- /dev/null +++ b/tests/vetting/oracles/volmin_phantom.py @@ -0,0 +1,153 @@ +"""bench_volmin_3d, the 3D texture fixture whose ROI holds the volume's lowest intensity, and its control. + + python tests/vetting/oracles/volmin_phantom.py (check the checked-in NIfTI files) + python tests/vetting/oracles/volmin_phantom.py --write (write them) + +An 8x14x14 int16 volume, CT-like: an ellipsoid ROI (label 1) whose bounding box has background in +its corners, at intensities -1024 + 25 ((3x + 5y + 7z + xyz) mod 17), i.e. 17 levels over +[-1024, -624]; every other voxel at -600 + ((x + 2y + 3z) mod 50). So the volume's lowest intensity, +-1024, is carried by ROI voxels. + +Nyxus stores a volume's intensities offset by its lowest one, so those ROI voxels are stored as 0, +the value the bounding box's background cells hold too. What a 3D texture family must do: bin them +like any other ROI voxel -- under N PyRadiomics-style bins the ROI's lowest level is bin 1 -- and +leave the background out. PyRadiomics and MIRP read the ROI's own intensities, so they are the judge. + +The control, bench_volmin_ctrl_3d, is the same volume with one voxel outside the ROI's bounding box, +(z, y, x) = (0, 0, 0), at -2000: the volume's lowest intensity is then not the ROI's, no ROI voxel is +stored as 0, and the ROI's intensities -- hence every oracle value -- are unchanged. A family must +give the same values on both. + +At a bin count of 8 the bin width is 50, so every other ROI level (n (x - min) a multiple of the range) +sits exactly on a bin edge. + +numpy is the only dependency. The generators that pin oracles on this fixture load it from here: +gen_{glcm,gldm,glrlm,glszm}3d_pyradiomics.py and gen_{gldzm,ngldm}3d_mirp.py. +""" +import os +import sys + +import numpy as np + +HERE = os.path.dirname(os.path.abspath(__file__)) +TESTS = os.path.dirname(os.path.dirname(HERE)) +PHANTOMS = os.path.join(TESTS, "data", "nifti", "phantoms") +INTEN = os.path.join(PHANTOMS, "volmin_inten.nii") +CTRL_INTEN = os.path.join(PHANTOMS, "volmin_ctrl_inten.nii") +MASK = os.path.join(PHANTOMS, "volmin_mask.nii") + +LABEL = 1 +NBINS = 8 +Z, Y, X = 8, 14, 14 +ROI_MIN = -1024 +CTRL_MIN = -2000 + +NIFTI_INT16 = 4 +NIFTI_UINT8 = 2 +NIFTI_DTYPE = {NIFTI_UINT8: np.uint8, NIFTI_INT16: np.int16} + + +def build(): + """-> (intensities, control intensities, mask), each shaped (z, y, x).""" + z, y, x = np.indices((Z, Y, X)) + roi = (((z - (Z - 1) / 2) / 3.6) ** 2 + ((y - (Y - 1) / 2) / 6.2) ** 2 + + ((x - (X - 1) / 2) / 6.2) ** 2) <= 1.0 + inten = np.where(roi, + ROI_MIN + 25 * ((3 * x + 5 * y + 7 * z + x * y * z) % 17), + -600 + (x + 2 * y + 3 * z) % 50).astype(np.int16) + ctrl = inten.copy() + ctrl[0, 0, 0] = CTRL_MIN + mask = np.where(roi, LABEL, 0).astype(np.uint8) + return inten, ctrl, mask + + +def check_fixture(inten, ctrl, mask): + """Raises unless the arrays have the properties the module docstring claims.""" + roi = mask == LABEL + zz, yy, xx = np.nonzero(roi) + box = (np.ptp(zz) + 1) * (np.ptp(yy) + 1) * (np.ptp(xx) + 1) + if not roi.sum() < box: + raise RuntimeError("the ROI fills its bounding box; it must leave background in it") + if inten.min() != ROI_MIN or inten[~roi].min() <= ROI_MIN: + raise RuntimeError("the volume's lowest intensity must be the ROI's alone") + if (inten[roi] == ROI_MIN).sum() < 2: + raise RuntimeError("the ROI must carry the volume's lowest intensity on several voxels") + if roi[0, 0, 0] or (zz.min() == 0 and yy.min() == 0 and xx.min() == 0): + raise RuntimeError("the control's moved voxel must lie outside the ROI's bounding box") + if ctrl.min() != CTRL_MIN or not np.array_equal(ctrl[roi], inten[roi]): + raise RuntimeError("the control must move only the volume minimum, outside the ROI") + levels = np.unique(inten[roi]) + bins = np.minimum(np.floor(NBINS * (levels - levels.min()) / (levels.max() - levels.min())) + 1, NBINS) + if len(np.unique(bins)) < NBINS: + raise RuntimeError("the ROI must populate every one of the %d bins" % NBINS) + + +def read_nifti(path): + """-> array shaped (z, y, x). Uncompressed single-file NIfTI-1 only.""" + with open(path, "rb") as fh: + raw = fh.read() + if int(np.frombuffer(raw, np.int32, 1, 0)[0]) != 348 or raw[344:347] != b"n+1": + raise RuntimeError(path + " is not an uncompressed single-file NIfTI-1") + dim = np.frombuffer(raw, np.int16, 8, 40) + datatype = int(np.frombuffer(raw, np.int16, 1, 70)[0]) + vox_offset = int(np.frombuffer(raw, np.float32, 1, 108)[0]) + nx, ny, nz = int(dim[1]), int(dim[2]), int(dim[3]) + return np.frombuffer(raw, NIFTI_DTYPE[datatype], nx * ny * nz, vox_offset).reshape((nz, ny, nx)) + + +def write_nifti(path, vol, datatype): + """Writes 'vol' as an uncompressed single-file NIfTI-1 at 1x1x1 spacing.""" + nz, ny, nx = vol.shape + bitpix = 8 * np.dtype(NIFTI_DTYPE[datatype]).itemsize + hdr = bytearray(352) + hdr[0:4] = np.array([348], np.int32).tobytes() + hdr[40:56] = np.array([3, nx, ny, nz, 1, 1, 1, 1], np.int16).tobytes() + hdr[70:72] = np.array([datatype], np.int16).tobytes() + hdr[72:74] = np.array([bitpix], np.int16).tobytes() + hdr[76:108] = np.array([0, 1, 1, 1, 1, 1, 1, 1], np.float32).tobytes() + hdr[108:112] = np.array([352.0], np.float32).tobytes() + hdr[148:228] = b"nyxus 3d texture volume-minimum phantom".ljust(80, b"\0") + hdr[254:256] = np.array([1], np.int16).tobytes() # sform_code + hdr[280:296] = np.array([1, 0, 0, 0], np.float32).tobytes() # srow_x + hdr[296:312] = np.array([0, 1, 0, 0], np.float32).tobytes() # srow_y + hdr[312:328] = np.array([0, 0, 1, 0], np.float32).tobytes() # srow_z + hdr[344:348] = b"n+1\0" + with open(path, "wb") as fh: + fh.write(bytes(hdr)) + fh.write(vol.astype(NIFTI_DTYPE[datatype]).tobytes()) + + +def files(): + """-> [(path, array, NIfTI datatype)] of the three checked-in files.""" + inten, ctrl, mask = build() + return [(INTEN, inten, NIFTI_INT16), (CTRL_INTEN, ctrl, NIFTI_INT16), (MASK, mask, NIFTI_UINT8)] + + +def check_files(): + """-> the number of checked-in files that do not hold what build() produces (0 when all do).""" + bad = 0 + for path, vol, _ in files(): + name = os.path.basename(path) + if not os.path.exists(path): + print(" FAIL %s is missing; run volmin_phantom.py --write" % name) + bad += 1 + elif not np.array_equal(read_nifti(path), vol): + print(" FAIL %s does not hold what volmin_phantom.build() produces" % name) + bad += 1 + else: + print(" OK %s is what volmin_phantom.build() produces" % name) + return bad + + +def main(): + check_fixture(*build()) + if "--write" in sys.argv[1:]: + for path, vol, datatype in files(): + write_nifti(path, vol, datatype) + print("# wrote " + path) + return 0 + return 1 if check_files() else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/vetting/report_output.csv b/tests/vetting/report_output.csv index 379782761..5c73ea502 100644 --- a/tests/vetting/report_output.csv +++ b/tests/vetting/report_output.csv @@ -730,307 +730,387 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 3D,glcm,3GLCM_SUMENTROPY,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=2e-3,agreed,,,,,audit,pyradiomics,test_3d_glcm_sum_entropy_pyradiomics;test_3d_glcm_sumentropy_ave_pyradiomics,test_3d_glcm_sum_entropy_regression,,2,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is 7.6e-4. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only). That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." 3D,glcm,3GLCM_SUMVARIANCE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,"pyradiomics/mirp (DIS=DifferenceAverage, HOM1=Id, HOM2=Idm, SUMVAR=ClusterTendency, ENERGY=JointEnergy=ASM, VAR=mirp cm_var); CONFIG-SENSITIVE: symmetric+13dir vs Nyxus asym/1-offset/100lvl",audit,pyradiomics,test_3d_glcm_equivalence_dump_pyradiomics,test_3d_glcm_sum_variance_regression;test_3d_glcm_sumvariance_grey64_regression,,1,2,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is <= 1.2e-15. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only)." 3D,glcm,3GLCM_VARIANCE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,"pyradiomics/mirp (DIS=DifferenceAverage, HOM1=Id, HOM2=Idm, SUMVAR=ClusterTendency, ENERGY=JointEnergy=ASM, VAR=mirp cm_var); CONFIG-SENSITIVE: symmetric+13dir vs Nyxus asym/1-offset/100lvl",audit,pyradiomics,test_3d_glcm_equivalence_dump_pyradiomics,test_3d_glcm_variance_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20, PER DIRECTION: the assertion in test_3d_glcm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glcm_3d_pyradiomics_ref_vals_by_angle), not the average of them - an average agrees whenever per-direction errors cancel. Both sides are symmetric here (Nyxus symmetrises under radiomics grey binning, 3d_glcm.cpp), so the measured residual is <= 1.2e-15. Goldens and the angle mapping from gen_glcm3d_pyradiomics.py. test_3d_glcm_regression.h pins Nyxus' own values on a different phantom and bin count and claims no oracle (drift guard only)." -3D,glcm,3GLCM_ASM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_asm_ave_pyradiomics;test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_asm_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_ACOR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_acor_ave_pyradiomics,test_3d_glcm_acor_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_CLUPROM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_cluprom_ave_pyradiomics,test_3d_glcm_cluprom_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_CLUSHADE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_clushade_ave_pyradiomics,test_3d_glcm_clushade_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_CLUTEND_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_clutend_ave_pyradiomics,test_3d_glcm_clutend_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_CONTRAST_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_contrast_ave_pyradiomics,test_3d_glcm_contrast_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_CORRELATION_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_correlation_ave_pyradiomics,test_3d_glcm_correlation_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_DIFAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_difave_ave_pyradiomics,test_3d_glcm_difave_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_ASM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,analytic;pyradiomics,test_3d_glcm_asm_ave_pyradiomics;test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_asm_ave_grey64_regression,test_3d_glcm_compatibility,5,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_ASM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,analytic;pyradiomics,test_3d_glcm_asm_ave_pyradiomics;test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_asm_ave_grey64_regression,test_3d_glcm_compatibility,5,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_ASM_AVE,vetted,analytic,glcm3d.analytic_matlab_background,rel=1e-9,agreed,bench_ellipsoid6x40x40_boxbg_3d,,,,in-tree,analytic;pyradiomics,test_3d_glcm_asm_ave_pyradiomics;test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_asm_ave_grey64_regression,test_3d_glcm_compatibility,5,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs the definition at recipe glcm3d.analytic_matlab_background: MATLAB-style binning at the default coarse grey depth 64 on bench_ellipsoid6x40x40_boxbg_3d, an ellipsoid ROI whose bounding box has background in it, in RAM and out of core. The reference, evaluated in numpy inside the test, counts for each of the 13 offsets at distance 1 the ordered pairs of ROI voxels by their MATLAB levels, floor(64 x / max + 1) clipped to 1..64, and takes ASM (sum p^2) of each normalised matrix, averaged over the 13. A family that reads the bounding box's background as level 1 counts every ROI-background pair and parts from it on the ellipsoid; test_3d_glcm_matlab_box_analytic, a ROI that fills its bounding box, is the negative case that holds either way. Asserted at rel=1e-9 by test_3d_glcm_matlab_background_analytic in tests/python/test_3d_glcm_analytic.py, a pytest case, so test_name is empty." +3D,glcm,3GLCM_ACOR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_acor_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_acor_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_ACOR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_acor_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_acor_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_CLUPROM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_cluprom_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_cluprom_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_CLUPROM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_cluprom_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_cluprom_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_CLUSHADE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_clushade_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_clushade_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_CLUSHADE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_clushade_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_clushade_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_CLUTEND_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_clutend_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_clutend_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_CLUTEND_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_clutend_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_clutend_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_CONTRAST_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,analytic;pyradiomics,test_3d_glcm_contrast_ave_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_contrast_ave_grey64_regression,test_3d_glcm_compatibility,4,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_CONTRAST_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,analytic;pyradiomics,test_3d_glcm_contrast_ave_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_contrast_ave_grey64_regression,test_3d_glcm_compatibility,4,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_CONTRAST_AVE,vetted,analytic,glcm3d.analytic_matlab_background,rel=1e-9,agreed,bench_ellipsoid6x40x40_boxbg_3d,,,,in-tree,analytic;pyradiomics,test_3d_glcm_contrast_ave_pyradiomics;test_3d_glcm_matlab_background_analytic;test_3d_glcm_matlab_box_analytic;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_contrast_ave_grey64_regression,test_3d_glcm_compatibility,4,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs the definition at recipe glcm3d.analytic_matlab_background: MATLAB-style binning at the default coarse grey depth 64 on bench_ellipsoid6x40x40_boxbg_3d, an ellipsoid ROI whose bounding box has background in it, in RAM and out of core. The reference, evaluated in numpy inside the test, counts for each of the 13 offsets at distance 1 the ordered pairs of ROI voxels by their MATLAB levels, floor(64 x / max + 1) clipped to 1..64, and takes CONTRAST (sum (i - j)^2 p) of each normalised matrix, averaged over the 13. A family that reads the bounding box's background as level 1 counts every ROI-background pair and parts from it on the ellipsoid; test_3d_glcm_matlab_box_analytic, a ROI that fills its bounding box, is the negative case that holds either way. Asserted at rel=1e-9 by test_3d_glcm_matlab_background_analytic in tests/python/test_3d_glcm_analytic.py, a pytest case, so test_name is empty." +3D,glcm,3GLCM_CORRELATION_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_correlation_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_correlation_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_CORRELATION_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_correlation_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_correlation_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_DIFAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_difave_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_difave_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_DIFAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_difave_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_difave_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glcm,3GLCM_DIFENTRO_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=3e-3,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_difentro_ave_pyradiomics,test_3d_glcm_difentro_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 1.2e-3. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." -3D,glcm,3GLCM_DIFVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_difvar_ave_pyradiomics,test_3d_glcm_difvar_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_DIFVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_difvar_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_difvar_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_DIFVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_difvar_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_difvar_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glcm,3GLCM_DIS_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_dis_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." 3D,glcm,3GLCM_ENERGY_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_energy_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." 3D,glcm,3GLCM_ENTROPY_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_entropy_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." 3D,glcm,3GLCM_HOM1_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_hom1_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_ID_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_id_ave_pyradiomics,test_3d_glcm_id_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_IDN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_idn_ave_pyradiomics,test_3d_glcm_idn_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_IDM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_idm_ave_pyradiomics,test_3d_glcm_idm_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_IDMN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_idmn_ave_pyradiomics,test_3d_glcm_idmn_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_IV_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_iv_ave_pyradiomics,test_3d_glcm_iv_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_JAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_jave_ave_pyradiomics,test_3d_glcm_jave_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_ID_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_id_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_id_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_ID_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_id_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_id_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_IDN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_idn_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idn_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_IDN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_idn_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idn_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_IDM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_idm_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idm_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_IDM_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_idm_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idm_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_IDMN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glcm_idmn_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idmn_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_IDMN_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_idmn_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_idmn_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_IV_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_iv_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_iv_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_IV_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_iv_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_iv_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_JAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_jave_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jave_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_JAVE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_jave_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jave_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glcm,3GLCM_JE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-3,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_je_ave_pyradiomics,test_3d_glcm_je_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 4.1e-4. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." 3D,glcm,3GLCM_INFOMEAS1_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=4e-2,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_infomeas1_ave_pyradiomics,test_3d_glcm_infomeas1_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 1.7e-2. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." 3D,glcm,3GLCM_INFOMEAS2_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=2e-2,agreed,,,,,audit,pyradiomics,test_3d_glcm_infomeas2_ave_pyradiomics,test_3d_glcm_infomeas2_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 7.7e-3. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." 3D,glcm,3GLCM_VARIANCE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_variance_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_JMAX_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_jmax_ave_pyradiomics,test_3d_glcm_jmax_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_JVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_jvar_ave_pyradiomics,test_3d_glcm_jvar_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." -3D,glcm,3GLCM_SUMAVERAGE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_sumaverage_ave_pyradiomics,test_3d_glcm_sumaverage_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_JMAX_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_jmax_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jmax_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_JMAX_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_jmax_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jmax_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_JVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_jvar_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jvar_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_JVAR_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics;test_3d_glcm_jvar_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_jvar_ave_grey64_regression,test_3d_glcm_compatibility,3,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glcm,3GLCM_SUMAVERAGE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_sumaverage_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_sumaverage_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." +3D,glcm,3GLCM_SUMAVERAGE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glcm_sumaverage_ave_pyradiomics;test_3d_glcm_volmin_pyradiomics,test_3d_glcm_sumaverage_ave_grey64_regression,test_3d_glcm_compatibility,2,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glcm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glcm_volmin_pyradiomics in tests/python/test_3d_glcm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLCM_DIFENTRO_AVE, 3GLCM_INFOMEAS1_AVE, 3GLCM_INFOMEAS2_AVE, 3GLCM_JE_AVE and 3GLCM_SUMENTROPY_AVE carry Nyxus' fast_log10 approximation and so stay out of the table. tests/vetting/oracles/gen_glcm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glcm,3GLCM_SUMENTROPY_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=2e-3,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_sumentropy_ave_pyradiomics,test_3d_glcm_sumentropy_ave_grey64_regression,test_3d_glcm_compatibility,1,1,also asserted by test_3d_glcm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 7.6e-4. That band is Nyxus' fast_log10 (helpers.h), a float-precision log2 approximation used by every entropy-family GLCM feature, not a convention difference." 3D,glcm,3GLCM_SUMVARIANCE_AVE,vetted,pyradiomics,glcm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,mirp,audit,pyradiomics,test_3d_glcm_ave_equivalence_pyradiomics,test_3d_glcm_sumvariance_ave_grey64_regression,,1,1,,,agree,feature,audit/glcm_3d_pyradiomics_vetting_report.md,audit/glcm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glcm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it, so a defect in how save_value populates *_AVE fails here. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 1.2e-15." 3D,gldm,3GLDM_DE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=4e-3,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. 3GLDM_DE is the exception at abs=4e-3: it is the family's only sum over logarithms and Nyxus takes it through fast_log10(), a float-precision approximation divided by a ten-digit LOG10_2, where PyRadiomics uses numpy.log2. Measured residual 1.7512e-3 absolute / 2.65e-4 relative (Nyxus 6.6031219389041276 against PyRadiomics 6.6048731874541904); the band is that doubled and rounded up to one significant figure. A documented fast path, banded rather than reported. Note the 2D twin's identical calc_DE() measures 1.3e-3 RELATIVE, five times wider, so this figure is this family's own and not carried across. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." 3D,gldm,3GLDM_DE,regression,,gldm3d.regression_ut_phantom,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band." 3D,gldm,3GLDM_DE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_de_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md. 3GLDM_DE is the family's only logarithm and is banded at rel=1e-6 rather than the exact tier: calc_DE() takes it through fast_log10(), whose float expression clang on arm64 contracts into fused multiply-adds where MSVC on x86-64 does not, so a pin taken on one platform does not survive rel=1e-9 on the other. Measured: both snapshot configurations failed on macOS-arm64 at rel=1e-9 while all thirteen non-logarithm features of both tables passed there. test_3d_glrlm_regression.h and test_3d_glszm_regression.h carry the identical carve-out for 3GLRLM_RE and 3GLSZM_ZE at the same band." -3D,gldm,3GLDM_DE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_dn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DNN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_dnn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_dv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_DV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_GLN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_gln_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_GLV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_glv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_HGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_hgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_lde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_ldhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_ldlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. Specific to this feature: the retired table pinned 3GLDM_LGLE at 0.26, byte-identical to the 3GLDM_SDE pin beside it, against a measured 0.00073572128237550161 - a factor of 353 - and test_3d_gldm_lgle_regression() asserted Feature3D::GLDM_SDE under the _lgle_ name, so the feature had no drift guard at all and 3GLDM_SDE had two. Both halves of one paste, in a file nothing ran." -3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,2,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_sde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_sdhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." -3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." -3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_sdlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,2,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. A fix is still not one line: at radiomics binning TextureFeature::to_grayscale_radiomix() computes binW = (max - min) / binCount, zero here, so every voxel bins to background and the Nz == 0 branch emits the same sentinel by a second route -- and that route divides by zero and converts NaN to PixIntens, which the intercept is what keeps unreachable. That is why this cell is asserted at GLDM_GREYDEPTH=0, where the intercept stands alone. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." -3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_sde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp,test_3d_gldzm_sde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_lde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_lglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_lglze_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_hglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_hglze_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_sdlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp,test_3d_gldzm_sdlgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_sdhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp,test_3d_gldzm_sdhgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_ldlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldlgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_ldhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_ldhgle_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_glnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnu_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_glnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glnun_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_zdnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_zdnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_zp_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldm,3GLDM_DE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_de_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_de_nobinning_regression;test_3d_gldm_de_regression,,2,3,"the family's only sum over logarithms; banded at abs=4e-3 against a measured 1.7512e-3 for fast_log10(), where the other thirteen hold at abs=1e-9",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,3,3,,test_3d_gldm_dn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,3,3,,test_3d_gldm_dn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_DN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,3,3,,test_3d_gldm_dn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DN,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dn_nobinning_regression;test_3d_gldm_dn_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_DNN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,3,3,,test_3d_gldm_dnn_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,3,3,,test_3d_gldm_dnn_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DNN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,3,3,,test_3d_gldm_dnn_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DNN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DNN,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dnn_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dnn_nobinning_regression;test_3d_gldm_dnn_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_DV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_DV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,3,3,,test_3d_gldm_dv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,3,3,,test_3d_gldm_dv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_DV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_DV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,3,3,,test_3d_gldm_dv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_DV,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_dv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_dv_nobinning_regression;test_3d_gldm_dv_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_GLN,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,3,3,,test_3d_gldm_gln_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,3,3,,test_3d_gldm_gln_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLN_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,3,3,,test_3d_gldm_gln_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLN,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLN,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_gln_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_gln_nobinning_regression;test_3d_gldm_gln_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_GLV,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,3,3,,test_3d_gldm_glv_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,3,3,,test_3d_gldm_glv_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_GLV_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,3,3,,test_3d_gldm_glv_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLV,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_GLV,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_glv_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_glv_nobinning_regression;test_3d_gldm_glv_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_HGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,3,3,,test_3d_gldm_hgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,3,3,,test_3d_gldm_hgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_HGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,3,3,,test_3d_gldm_hgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_HGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_HGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_hgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_hgle_nobinning_regression;test_3d_gldm_hgle_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_LDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,3,3,,test_3d_gldm_lde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,3,3,,test_3d_gldm_lde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,3,3,,test_3d_gldm_lde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lde_nobinning_regression;test_3d_gldm_lde_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_LDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,3,3,,test_3d_gldm_ldhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,3,3,,test_3d_gldm_ldhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,3,3,,test_3d_gldm_ldhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldhgle_nobinning_regression;test_3d_gldm_ldhgle_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_LDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,3,3,,test_3d_gldm_ldlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,3,3,,test_3d_gldm_ldlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,3,3,,test_3d_gldm_ldlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_ldlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_ldlgle_nobinning_regression;test_3d_gldm_ldlgle_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_LGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,3,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,3,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md. Specific to this feature: the retired table pinned 3GLDM_LGLE at 0.26, byte-identical to the 3GLDM_SDE pin beside it, against a measured 0.00073572128237550161 - a factor of 353 - and test_3d_gldm_lgle_regression() asserted Feature3D::GLDM_SDE under the _lgle_ name, so the feature had no drift guard at all and 3GLDM_SDE had two. Both halves of one paste, in a file nothing ran." +3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_LGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,3,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_lgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,3,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_LGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_lgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_lgle_nobinning_regression;test_3d_gldm_lgle_regression,,3,3,"the retired snapshot pinned this to 3GLDM_SDE's value (0.26 against a measured 0.00073572), under a function that asserted 3GLDM_SDE; both halves regenerated",,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_SDE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,3,3,,test_3d_gldm_sde_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,3,3,,test_3d_gldm_sde_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,3,3,,test_3d_gldm_sde_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sde_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sde_nobinning_regression;test_3d_gldm_sde_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_SDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,3,3,,test_3d_gldm_sdhgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,3,3,,test_3d_gldm_sdhgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDHGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,3,3,,test_3d_gldm_sdhgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDHGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDHGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdhgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdhgle_nobinning_regression;test_3d_gldm_sdhgle_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldm,3GLDM_SDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_bincount20,abs=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,3,3,,test_3d_gldm_sdlgle_pyradiomics,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 GLDM on the compat phantom (bench_compat_liver_3d, label 1), recipe gldm3d.pyradiomics_bincount20. Nyxus' GLDM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels; both sides walk the full 26-voxel neighbourhood at Chebyshev distance 1 with the dependence cutoff alpha=0, and both start the dependence count at 1 so a voxel with no dependent neighbour lands in the same column. No convention separates them, which is why SPEC 7's exact tier applies: the measured residual is at most 7.11e-15 ABSOLUTE (3GLDM_SDHGLE) and 8.79e-16 relative across the thirteen features that take no logarithm, eight of them exactly 0, asserted with ASSERT_NEAR at abs=1e-9. Backed by THE FOURTEEN SCALARS AND THE MATRIX THEY CONTRACT: all fourteen are sums over one P(i,j) dependence matrix, so TEST_3D_GLDM_MATRIX_PYRADIOMICS pins that matrix too - all 163 non-empty cells, its Ng/Nd/Nz/Np, and the count of populated cells - against PyRadiomics' own P_gldm array, read through its ivector AND jvector because PyRadiomics deletes the rows of absent grey levels and the columns of absent dependences. Nz == Np is asserted from the cube rather than the matrix, which is what says Nyxus counts no voxel outside the ROI into the matrix. The assertion reads the cube the same extraction produced, so perturbing one voxel of it fails. TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS runs the same assertion on a 4x4x3 volume whose two populated slices are identical, forcing every dependence to 2*(in-slice matches)+2 - the direct check that the neighbourhood includes the z offsets. The generator rebuilds the matrix from the definition independently of PyRadiomics' C extension and requires all 163 cells to agree. test_3d_gldm_regression.h pins Nyxus' own values on the ut phantom at recipe gldm3d.regression_ut_phantom and claims no oracle. Evidence: tests/vetting/audit/gldm_3d_pyradiomics_vetting_report.md, generator tests/vetting/oracles/gen_gldm3d_pyradiomics.py. Neither matrix case is named in test_name: TEST_NYXUS.TEST_3D_GLDM_MATRIX_PYRADIOMICS asserts the cells of P rather than this feature's value, and TEST_NYXUS.TEST_3D_GLDM_SMALLMATRIX_PYRADIOMICS asserts them on a hand-written unbinned 4x4x3 volume that is not this row's benchmark and not this row's recipe. Both are corroboration for the recipe, recorded here; test_name keeps the one case that asserts the value this row claims." +3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,3,3,,test_3d_gldm_sdlgle_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom (bench_ut57_3d, label 57, GREYDEPTH=64 / GLDM_GREYDEPTH=64 / IBSI=false); establishes no vetting (SPEC 1). This is a different configuration from the PyRadiomics recipe, not a second opinion on it: GLDM_GREYDEPTH's positive sign selects MATLAB-style level-count binning where the oracle recipe's negative sign selects PyRadiomics-style bin counting. The pins are regenerated at %.17g rather than carried over, because the previous table could not be reproduced at any configuration: at GLDM_GREYDEPTH=0 - what a settings vector that never names the family's binning reaches - the values are three orders away (3GLDM_HGLE 4275550.79 against a pinned 1957.2), while at GLDM_GREYDEPTH=64 the grey-level axis reproduces to 4-5 digits (3GLDM_HGLE 1957.1946, 3GLDM_GLN 6480.830, 3GLDM_GLV 153.0947, 3GLDM_DE 8.40347) and every quantity touching the dependence axis does not (3GLDM_SDE 1.69x, 3GLDM_LDE 0.86x, 3GLDM_DV 0.93x, and all four grey-by-dependence cross-terms). The file was never #included, so none of it had ever run. It is wired into test_all.cc here. Evidence: tests/vetting/audit/gldm_3d_golden_regen.md." +3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDM_SDLGLE_NOBINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,3,3,,test_3d_gldm_sdlgle_nobinning_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Snapshot drift guard only, recipe gldm3d.regression_ut_phantom_nobinning (bench_ut57_3d, label 57, GLDM_GREYDEPTH=0, IBSI=false); establishes no vetting (SPEC 1). GLDM_GREYDEPTH=0 IS THE NO-BINNING PRODUCTION POINT: --coarseGrayDepth=0 or 3gldm/greydepth=0 selects it, and IBSI=true reaches the same code path by forcing greyInfo=0. A run that names neither bins at the coarse grey depth, 64 -- Environment::compile_feature_settings() starts GLDM_GREYDEPTH there -- which is recipe gldm3d.regression_ut_phantom. Under SPEC 5.1 that is VALID-BUT-PRODUCTION-ONLY, which is a regression row. The gldm3d.regression_ut_phantom pins cannot stand in for it: on the same ROI the two configurations differ by orders of magnitude (3GLDM_HGLE 4275550.79 against 1957.19, 3GLDM_SDE 0.86996 against 0.15361, 3GLDM_GLV 341996.30 against 153.09), so a pin taken at 64 guards nothing at 0. GREYDEPTH is inert for this family and is held at the neighbouring recipe's 64 so the two tables differ in the one setting under test. No oracle claim: whether PyRadiomics can be made to skip discretisation on a non-integer intensity volume has not been answered. Pins regenerated at %.17g by test_3d_gldm_dump_nobinning_regression(). Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDLGLE,regression,,gldm3d.regression_constant_roi,exact,,bench_constant_roi_3d,TEST_NYXUS.TEST_3D_GLDM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,3,3,,test_3d_gldm_constant_roi_regression,agree,row+config,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"Defect guard, recipe gldm3d.regression_constant_roi (bench_constant_roi_3d, GLDM_GREYDEPTH=0); establishes no vetting (SPEC 1) and endorses nothing. A NONEMPTY ROI OF ONE INTENSITY comes back as the configured no-value sentinel for all fourteen features -- production defaults it to 0.0 (ResultOptions::noval_), a value several of the fourteen also compute legitimately. D3_GLDM_feature::calculate()'s aux_min == aux_max intercept emits it -- written for BLANK ROIs, but tested on the intensity extrema. THE ARITHMETIC UNDER THE INTERCEPT IS NOT WRONG: restricting the intercept to empty cubes as a negative control, at this recipe's GLDM_GREYDEPTH=0, Nyxus reproduces PyRadiomics on all seven dependence-axis features to the last bit (SDE 0.0066408036122542298, LDE 239.41666666666666, DN 15.333333333333334, DNN 0.31944444444444442, DV 26.743055555555554, GLN 48, GLV 0), 3GLDM_DE differs by the family's documented fast_log10 residual, and the grey-level features differ only because no-binning keeps the raw intensity 7 as the level where binWidth=1 maps it to 1. The intercept is the whole defect. Beneath the intercept every binning scheme has a matrix to answer with: at radiomics binning TextureFeature::fixed_bin_number() puts a range of zero width into one bin, so every voxel is level 1 there. This cell is asserted at GLDM_GREYDEPTH=0 because that is where the bypass was measured against PyRadiomics. The case runs under a sentinel of -98765.0 so a pass says the intercept fired rather than the features happening to compute zero. Such an ROI is reachable wherever a segmentation lands on a flat or saturated region, and its dependence matrix is well defined: PyRadiomics 3.0.1 computes it on the same 4x4x3 voxels at binWidth=1, gldm_a=0, distances=[1] -- P_gldm 1x4 = [8, 20, 16, 4] over one grey level, SDE 0.0066408036122542298, LDE 239.41666666666666, DE 1.7841591278514204, GLN 48. So this is a divergence Nyxus owns, not a convention difference. It is guarded rather than fixed here because the same intercept is shared by 3d_gldzm, 3d_glszm, 3d_ngldm, 3d_ngtdm and their 2D twins, so changing it moves production output well beyond this family. Evidence: tests/vetting/matrix/gldm3d.md." +3D,gldm,3GLDM_SDLGLE,vetted,pyradiomics,gldm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_gldm_compatibility;test_3d_gldm_sdlgle_pyradiomics;test_3d_gldm_volmin_pyradiomics,test_3d_gldm_constant_roi_regression;test_3d_gldm_sdlgle_nobinning_regression;test_3d_gldm_sdlgle_regression,,3,3,,,agree,feature,audit/gldm_3d_pyradiomics_vetting_report.md,audit/gldm_3d_golden_regen.md,matrix/gldm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe gldm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldm_volmin_pyradiomics in tests/python/test_3d_gldm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLDM_DE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_gldm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sde_regression,,4,1,,test_3d_gldzm_sde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sde_regression,,4,1,,test_3d_gldzm_sde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sde_regression,,4,1,,test_3d_gldzm_sde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sde_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_SDE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sde_mirp;test_3d_gldzm_sde_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sde_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lde_regression,,4,1,,test_3d_gldzm_lde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lde_regression,,4,1,,test_3d_gldzm_lde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lde_regression,,4,1,,test_3d_gldzm_lde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lde_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_lde_mirp;test_3d_gldzm_lde_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lde_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lglze_regression,,4,1,,test_3d_gldzm_lglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lglze_regression,,4,1,,test_3d_gldzm_lglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lglze_regression,,4,1,,test_3d_gldzm_lglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lglze_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LGLZE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_lglze_mirp;test_3d_gldzm_lglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_lglze_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_hglze_regression,,4,1,,test_3d_gldzm_hglze_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_hglze_regression,,4,1,,test_3d_gldzm_hglze_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_HGLZE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_hglze_regression,,4,1,,test_3d_gldzm_hglze_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_hglze_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_HGLZE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_hglze_mirp;test_3d_gldzm_hglze_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_hglze_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdlgle_regression,,4,1,,test_3d_gldzm_sdlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdlgle_regression,,4,1,,test_3d_gldzm_sdlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdlgle_regression,,4,1,,test_3d_gldzm_sdlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdlgle_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_SDLGLE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdlgle_mirp;test_3d_gldzm_sdlgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdlgle_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdhgle_regression,,4,1,,test_3d_gldzm_sdhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdhgle_regression,,4,1,,test_3d_gldzm_sdhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_SDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdhgle_regression,,4,1,,test_3d_gldzm_sdhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdhgle_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_SDHGLE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_sdhgle_mirp;test_3d_gldzm_sdhgle_radiomics_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_sdhgle_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldlgle_regression,,4,1,,test_3d_gldzm_ldlgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldlgle_regression,,4,1,,test_3d_gldzm_ldlgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDLGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldlgle_regression,,4,1,,test_3d_gldzm_ldlgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldlgle_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDLGLE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_ldlgle_mirp;test_3d_gldzm_ldlgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldlgle_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldhgle_regression,,4,1,,test_3d_gldzm_ldhgle_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldhgle_regression,,4,1,,test_3d_gldzm_ldhgle_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_LDHGLE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldhgle_regression,,4,1,,test_3d_gldzm_ldhgle_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldhgle_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_LDHGLE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_ldhgle_mirp;test_3d_gldzm_ldhgle_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_ldhgle_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnu_regression,,4,1,,test_3d_gldzm_glnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnu_regression,,4,1,,test_3d_gldzm_glnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnu_regression,,4,1,,test_3d_gldzm_glnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnu_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLNU,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_glnu_mirp;test_3d_gldzm_glnu_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnu_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnun_regression,,4,1,,test_3d_gldzm_glnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnun_regression,,4,1,,test_3d_gldzm_glnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnun_regression,,4,1,,test_3d_gldzm_glnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnun_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLNUN,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_glnun_mirp;test_3d_gldzm_glnun_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glnun_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,4,1,,test_3d_gldzm_zdnu_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,4,1,,test_3d_gldzm_zdnu_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNU_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,4,1,,test_3d_gldzm_zdnu_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDNU,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnu_mirp;test_3d_gldzm_zdnu_radiomics_mirp,test_3d_gldzm_zdnu_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,4,1,,test_3d_gldzm_zdnun_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,4,1,,test_3d_gldzm_zdnun_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDNUN_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,4,1,,test_3d_gldzm_zdnun_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDNUN,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdnun_mirp;test_3d_gldzm_zdnun_radiomics_mirp,test_3d_gldzm_zdnun_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,4,1,,test_3d_gldzm_zp_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,4,1,,test_3d_gldzm_zp_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZP_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,4,1,,test_3d_gldzm_zp_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZP,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zp_mirp;test_3d_gldzm_zp_radiomics_mirp,test_3d_gldzm_zp_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.mirp_compat_phantom,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_COMPAT_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_compat_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_GLM,regression,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLM_RADIOMICS_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_glm_compat_regression;test_3d_gldzm_glm_radiomics_regression;test_3d_gldzm_glm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_gl_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_glm_radiomics_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_glv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp,test_3d_gldzm_glv_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glv_regression,,4,1,,test_3d_gldzm_glv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glv_regression,,4,1,,test_3d_gldzm_glv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_GLV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glv_regression,,4,1,,test_3d_gldzm_glv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glv_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_GLV,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_glv_mirp;test_3d_gldzm_glv_radiomics_mirp;test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp,test_3d_gldzm_glv_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, and not vettable at any recipe: MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so no oracle in the tool matrix reaches this feature. PyRadiomics implements no GLDZM at all. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.mirp_compat_phantom,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_COMPAT_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_compat_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the no-binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" 3D,gldzm,3GLDZM_ZDM,regression,,gldzm3d.mirp_compat_phantom_radiomics,rel=1e-9,,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDM_RADIOMICS_REGRESSION,no-oracle,,in-tree,,,test_3d_gldzm_zdm_compat_regression;test_3d_gldzm_zdm_radiomics_regression;test_3d_gldzm_zdm_regression,,0,3,"no counterpart in any tool (MIRP's GLDZM emits no dzm_zd_mean column) and none in IBSI, so it is a drift guard at every recipe",test_3d_gldzm_zdm_radiomics_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard at the radiomics binning point of bench_compat_gldzm_3d. MIRP's GLDZM emits no dzm_gl_mean / dzm_zd_mean column and IBSI defines neither, so this feature has no oracle at any binning scheme -- but it is a Nyxus output at every one of them, so each config cell that carries oracle rows for the other sixteen carries a drift guard for this one rather than leaving the cell silently uncovered. Full %.17g precision, rel=1e-9. Report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_zdv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." -3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- to_grayscale_radiomix maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_zde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" -3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,3,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,4,1,,test_3d_gldzm_zdv_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,4,1,,test_3d_gldzm_zdv_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDV_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,4,1,,test_3d_gldzm_zdv_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-9 in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDV,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zdv_mirp;test_3d_gldzm_zdv_radiomics_mirp,test_3d_gldzm_zdv_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,4,1,,test_3d_gldzm_zde_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d, recipe gldzm3d.mirp_compat_phantom: MIRP by_slice=False with base_discretisation_method=none, Nyxus IBSI=true, so both read the phantom's voxel values as grey levels 1..8 and neither discretises. SPEC 7 exact tier, an absolute 1e-9 band; 13 of the 16 values are bit-identical to MIRP's doubles and the worst residual over the other three is an absolute 5.7e-15, on 3GLDZM_ZDE, the only one whose formula takes a logarithm. The phantom separates each of the family's three definition choices and each is negative-controlled: 6- or 18-connected zones fail all 16 assertions, the shortest-of-six-axis-rays distance fails 9 of 16. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_compat_phantom_radiomics,abs=1e-9,agreed,bench_compat_gldzm_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_RADIOMICS_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,4,1,,test_3d_gldzm_zde_radiomics_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs mirp 2.6.0 on bench_compat_gldzm_3d at the family's radiomics binning point, recipe gldzm3d.mirp_compat_phantom_radiomics: GREYDEPTH=-8, IBSI=false against MIRP by_slice=False with base_discretisation_method=none. At this bin count the radiomics scheme is the identity on the fixture's levels 1..8 -- IBSI's fixed bin number (TextureFeature::fixed_bin_number) maps them over a bin width of 7/8 back onto themselves, the top level clipping into the last bin -- so the point computes the GLDZM of the same grey levels the no-binning point does and MIRP's goldens apply unchanged. Asserted feature by feature against the tool at this cell's settings, not inferred from the no-binning cell; the equivalence itself is held by TEST_3D_GLDZM_RADIOMICS_BINNING_IS_IDENTITY_HERE_MECHANICS. SPEC 7 exact tier, an absolute 1e-9 band. It does not generalise to a bin count that actually re-bins; matrix/gldzm3d.md records that limit. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,regression,,gldzm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_ZDE_REGRESSION,discretisation-mismatch,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,4,1,,test_3d_gldzm_zde_regression,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"drift guard only, not vetted: the family's default mode cannot be compared with MIRP, because the two tools do not put this ROI on the same grey levels (MIRP's fixed_bin_number n=64 spreads it over 1-64, Nyxus' GREYDEPTH=64 binning over 22-64, 43 distinct). That gap is a property of the binning every Nyxus texture family shares, not of the GLDZM; matrix/gldzm3d.md records the fbn64 cell INVALID with the measurement. The family's vetting is at gldzm3d.mirp_compat_phantom. Generator tests/vetting/oracles/gen_gldzm3d_mirp.py, report tests/vetting/audit/gldzm_3d_mirp_vetting_report.md" +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLDZM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,4,1,,test_3d_gldzm_negative_greydepth_mirp,agree,row+config,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe gldzm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False. gldzm3d.mirp_compat_phantom_radiomics runs the same scheme where it is the identity on its fixture; this is the point where it re-bins. Measured residual 2.4e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_gldzm_mirp.h. gen_gldzm3d_mirp.py re-verifies every pin." +3D,gldzm,3GLDZM_ZDE,vetted,mirp,gldzm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_gldzm_negative_greydepth_mirp;test_3d_gldzm_volmin_mirp;test_3d_gldzm_zde_mirp;test_3d_gldzm_zde_radiomics_mirp,test_3d_gldzm_zde_regression,,4,1,,,agree,feature,audit/gldzm_3d_mirp_vetting_report.md,audit/gldzm_3d_golden_regen.md,matrix/gldzm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe gldzm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_gldzm_volmin_mirp in tests/python/test_3d_gldzm_mirp.py, a pytest case, so test_name is empty. tests/vetting/oracles/gen_gldzm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." 3D,ngldm,3NGLDM_DCP,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCP_REGRESSION,non-discriminating-agreement,,in-tree,,,test_3d_ngldm_dcp_regression,,0,1,"no oracle row: Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, so the agreement cannot fail",test_3d_ngldm_dcp_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would pin the same Nyxus run to a second literal and add no path or config coverage. This one carries no oracle row because Nyxus hard-codes f_DCP = 1 and MIRP returns 1 on any input where every voxel has a same-level neighbour, at both config points -- an agreement that cannot fail for the reasons an assertion should fail. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." 3D,ngldm,3NGLDM_GLM,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLM_REGRESSION,,,in-tree,,,test_3d_ngldm_glm_regression,,0,1,no counterpart in any tool (MIRP's NGLDM emits no gl_mean column),test_3d_ngldm_glm_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." 3D,ngldm,3NGLDM_DCM,regression,,ngldm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCM_REGRESSION,,,in-tree,,,test_3d_ngldm_dcm_regression,,0,1,no counterpart in any tool (MIRP's NGLDM emits no dc_mean column),test_3d_ngldm_dcm_regression,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"Snapshot drift guard only, recipe ngldm3d.regression_ut_phantom; establishes no vetting (SPEC 1). One of only three rows this family keeps here: the other 16 features are asserted against MIRP on this same fixture and config, so a snapshot of them would add no path or config coverage. This one carries no oracle row at any recipe because MIRP's NGLDM emits no gl_mean / dc_mean column, so no tool computes the quantity. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcent_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcene_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_lglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_ldhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_hdhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_glv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcent_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." -3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_dcene_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." -3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp,,,3,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_lde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hde_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_lglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hglce_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_ldlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_ldhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hdlgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hdhgle_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcnu_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcnun_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcv_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcent_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_samelevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_MIRP,scoped-oracle,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcene_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 8.7e-16 on Windows/MSVC). SCOPE, per SPEC 4: this oracle covers the NGLD matrix -- which voxels are centres, which neighbours count, how a dependence count maps to a matrix column -- and the feature formulas over it. It does NOT cover the discretisation: MIRP is handed the grey levels Nyxus' GREYDEPTH=64 binning produces, so the levels are an input to the comparison rather than a result of it, and Nyxus' binning is judged nowhere here. At MIRP's own fixed_bin_number n=64 the two tools do not share a level ladder (Nyxus 21-64, MIRP 1-64), which is recipe ngldm3d.mirp_fbn64 and carries no rows. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_lde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_lde_ibsi_mirp;test_3d_ngldm_lde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hde_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_hde_ibsi_mirp;test_3d_ngldm_hde_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_lglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LGLCE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_lglce_ibsi_mirp;test_3d_ngldm_lglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HGLCE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hglce_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HGLCE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_hglce_ibsi_mirp;test_3d_ngldm_hglce_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_ldlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDLGLE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_ldlgle_ibsi_mirp;test_3d_ngldm_ldlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_LDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_ldhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_LDHGLE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_ldhgle_ibsi_mirp;test_3d_ngldm_ldhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDLGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hdlgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDLGLE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_hdlgle_ibsi_mirp;test_3d_ngldm_hdlgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_HDHGLE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_hdhgle_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_HDHGLE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_hdhgle_ibsi_mirp;test_3d_ngldm_hdhgle_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLNU,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_glnu_ibsi_mirp;test_3d_ngldm_glnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLNUN,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_glnun_ibsi_mirp;test_3d_ngldm_glnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNU_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcnu_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCNU,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_dcnu_ibsi_mirp;test_3d_ngldm_dcnu_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCNUN_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcnun_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCNUN,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_dcnun_ibsi_mirp;test_3d_ngldm_dcnun_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_GLV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_glv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_GLV,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_glv_ibsi_mirp;test_3d_ngldm_glv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCV_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcv_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCV,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_dcv_ibsi_mirp;test_3d_ngldm_dcv_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENT_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcent_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-6,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-6, the family logarithm whose last bits move between platforms in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCENT,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_dcent_ibsi_mirp;test_3d_ngldm_dcent_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_ibsi_rawlevels,rel=1e-3,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_DCENE_IBSI_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_dcene_ibsi_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"MIRP 2.6.0 pin reproduced by tests/vetting/oracles/gen_ngldm3d_mirp.py; Nyxus agrees within rel=1e-3 (worst measured residual across the 16 is 7.54e-15). This is the family's IBSI=true config point: IBSI reaches to_grayscale as disable_binning, so nothing is binned and the raw loader-shifted intensity is the grey level (2001 distinct on this fixture). MIRP at base_discretisation_method=none over the same raw values is therefore config-matched by construction, with no discretisation step for the two to disagree about -- so unlike ngldm3d.mirp_samelevels this row's scope is not narrowed. A weak discriminator, measured: 83.46 percent of ROI voxels have no matching neighbour and the maximum dependence reached is 17 of 26. Evidence: tests/vetting/audit/ngldm_3d_mirp_vetting_report.md." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_fbn20_negdepth,rel=1e-9,agreed,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGLDM_NEGATIVE_GREYDEPTH_MIRP,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,test_3d_ngldm_negative_greydepth_mirp,agree,row,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP at the negative coarse grey depth, recipe ngldm3d.mirp_fbn20_negdepth: GREYDEPTH=-20 bins the ROI into 20 PyRadiomics-style bins over its own [min, max], IBSI's fixed bin number floor(20 (x - min) / (max - min)) + 1, and MIRP 2.6.0 runs base_discretisation_method=fixed_bin_number, n_bins=20 -- each tool discretising for itself, so the comparison covers the binning as well as the matrix and the formulas. Fixture bench_ut57_3d, label 57; MIRP is handed the integer levels Nyxus loads the float phantom as -- the loader's shift, not a binning step. by_slice=False, distance 1, difference level 0. Unlike ngldm3d.mirp_samelevels, nothing of Nyxus' binning is reproduced on the MIRP side. Measured residual 5.1e-16 worst case over the family; asserted at rel=1e-9 in test_3d_ngldm_mirp.h. gen_ngldm3d_mirp.py re-verifies every pin." +3D,ngldm,3NGLDM_DCENE,vetted,mirp,ngldm3d.mirp_volmin_fbn8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,mirp,test_3d_ngldm_dcene_ibsi_mirp;test_3d_ngldm_dcene_mirp;test_3d_ngldm_negative_greydepth_mirp;test_3d_ngldm_volmin_mirp,,,4,0,,,agree,feature,audit/ngldm_3d_mirp_vetting_report.md,audit/ngldm_3d_golden_regen.md,matrix/ngldm3d.md,"vetted vs MIRP 2.6.0 on bench_volmin_3d, recipe ngldm3d.mirp_volmin_fbn8: Nyxus coarse_gray_depth=-8, IBSI's fixed bin number over the ROI's own [min, max], against MIRP by_slice=False, base_discretisation_method=fixed_bin_number, n_bins=8 on the ROI's own intensities, distance 1, difference level 0 -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 and then lifts every level by one, or drops those voxels, parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_ngldm_volmin_mirp in tests/python/test_3d_ngldm_mirp.py, a pytest case, so test_name is empty; 3NGLDM_DCP is left out as at the family's other MIRP recipes, both tools returning 1 whenever every voxel has a same-level neighbour. tests/vetting/oracles/gen_ngldm3d_mirp.py re-verifies every pin at rel 1e-12 and that MIRP gives the control the same values." 3D,ngtdm,3NGTDM_COARSENESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_COARSENESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" -3D,ngtdm,3NGTDM_COARSENESS,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." +3D,ngtdm,3NGTDM_COARSENESS,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_COARSENESS_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_coarseness_pyradiomics;test_3d_ngtdm_coarseness_r2_pyradiomics,test_3d_ngtdm_coarseness_regression,test_3d_ngtdm_compatibility,2,1,"the matrix the five features contract is pinned per grey level as well, in test_3d_ngtdm_matrix_pyradiomics | also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression)",test_3d_ngtdm_coarseness_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." 3D,ngtdm,3NGTDM_CONTRAST,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_contrast_pyradiomics;test_3d_ngtdm_contrast_r2_pyradiomics,test_3d_ngtdm_contrast_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_contrast_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_CONTRAST,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_contrast_pyradiomics;test_3d_ngtdm_contrast_r2_pyradiomics,test_3d_ngtdm_contrast_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_contrast_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" -3D,ngtdm,3NGTDM_CONTRAST,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_contrast_pyradiomics;test_3d_ngtdm_contrast_r2_pyradiomics,test_3d_ngtdm_contrast_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_contrast_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." +3D,ngtdm,3NGTDM_CONTRAST,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_CONTRAST_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_contrast_pyradiomics;test_3d_ngtdm_contrast_r2_pyradiomics,test_3d_ngtdm_contrast_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_contrast_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." 3D,ngtdm,3NGTDM_BUSYNESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_busyness_pyradiomics;test_3d_ngtdm_busyness_r2_pyradiomics,test_3d_ngtdm_busyness_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_busyness_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_BUSYNESS,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_busyness_pyradiomics;test_3d_ngtdm_busyness_r2_pyradiomics,test_3d_ngtdm_busyness_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_busyness_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" -3D,ngtdm,3NGTDM_BUSYNESS,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_busyness_pyradiomics;test_3d_ngtdm_busyness_r2_pyradiomics,test_3d_ngtdm_busyness_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_busyness_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." +3D,ngtdm,3NGTDM_BUSYNESS,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_BUSYNESS_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_busyness_pyradiomics;test_3d_ngtdm_busyness_r2_pyradiomics,test_3d_ngtdm_busyness_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_busyness_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." 3D,ngtdm,3NGTDM_COMPLEXITY,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_complexity_pyradiomics;test_3d_ngtdm_complexity_r2_pyradiomics,test_3d_ngtdm_complexity_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_complexity_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_COMPLEXITY,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_complexity_pyradiomics;test_3d_ngtdm_complexity_r2_pyradiomics,test_3d_ngtdm_complexity_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_complexity_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" -3D,ngtdm,3NGTDM_COMPLEXITY,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_complexity_pyradiomics;test_3d_ngtdm_complexity_r2_pyradiomics,test_3d_ngtdm_complexity_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_complexity_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." +3D,ngtdm,3NGTDM_COMPLEXITY,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_COMPLEXITY_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_complexity_pyradiomics;test_3d_ngtdm_complexity_r2_pyradiomics,test_3d_ngtdm_complexity_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_complexity_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." 3D,ngtdm,3NGTDM_STRENGTH,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57), recipe ngtdm3d.pyradiomics_binwidth1. Both sides discretise the phantom's levels 0..5 to 1..6 -- PyRadiomics by binWidth=1, Nyxus by the zero-min correction at NGTDM_GREYDEPTH=0 -- so no binning convention separates them and the residual is 0 to the last bit; asserted at rel=1e-9. Backed by the FIVE SCALARS AND THE MATRIX THEY CONTRACT: all five features are sums over one (i, n_i, p_i, s_i) table of six grey levels, so test_3d_ngtdm_matrix_pyradiomics pins that table too, per level, against PyRadiomics' own P_ngtdm array. A planted 1e-8 error in one s_i fails the matrix assertion naming its level while all five scalars still pass. PyRadiomics' public extractor cannot load this phantom at all -- its mask is label 57 in all 48 voxels with no background, which imageoperations.getMask() rejects -- so the generator constructs RadiomicsNGTDM directly and cross-checks it against an independent numpy NGTDM (worst rel 2.7e-16). The ut_ phantom carries its own drift pins at recipe ngtdm3d.regression_ut_phantom, which are a different config point on a different fixture and have their own rows. gen_ngtdm3d_pyradiomics.py" 3D,ngtdm,3NGTDM_STRENGTH,vetted,pyradiomics,ngtdm3d.pyradiomics_binwidth1_r2,rel=1e-9,agreed,bench_compat_ngtdm_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_R2_PYRADIOMICS,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_r2_pyradiomics,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"vetted vs PyRadiomics 3.0.1 NGTDM on the 4x4x3 NGTDM phantom (label 57) at NGTDM_RADIUS=2, recipe ngtdm3d.pyradiomics_binwidth1_r2 -- the same phantom and the same binning as ngtdm3d.pyradiomics_binwidth1, differing only in the radius. Asserted at rel=1e-9 with residual 0. THE SECOND CONFIG POINT EXISTS BECAUSE ONE CANNOT SEPARATE HONOURING THE RADIUS FROM IGNORING IT: the radius is the axis a run gets wrong by leaving it unset, and at radius 2 every one of the five features moves by a quarter or more, so an implementation that clamped the radius to 1 would pass every radius-1 assertion and fail these. PyRadiomics' distances names Chebyshev SHELLS rather than a radius, so the match for a solid radius-2 neighbourhood is distances=[1, 2] and not [2]; distances_semantics_check() in the generator measures both readings every run and reports [2] at worst s_i rel 0.334 against the solid neighbourhood. Backed by the matrix as well as the scalars: test_3d_ngtdm_matrix_r2_pyradiomics pins the six-level (i, n_i, p_i, s_i) table these five features contract, per level, against PyRadiomics' own P_ngtdm array. The phantom is 4x4x3, so radius 3 already spans it from every voxel and supports no further config point. gen_ngtdm3d_pyradiomics.py" -3D,ngtdm,3NGTDM_STRENGTH,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style, which makes bin 1 the background level: a voxel binned there is no matrix row of its own but still counts towards its neighbours' neighbourhood means, and no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,ngtdm,3NGTDM_STRENGTH,regression,,ngtdm3d.regression_ut_phantom,rel=1e-9,na,bench_ut57_3d,TEST_NYXUS.TEST_3D_NGTDM_STRENGTH_REGRESSION,,,audit,pyradiomics,test_3d_ngtdm_strength_pyradiomics;test_3d_ngtdm_strength_r2_pyradiomics,test_3d_ngtdm_strength_regression,test_3d_ngtdm_compatibility,2,1,also asserted by test_3d_ngtdm_compatibility (kind is neither oracle nor regression),test_3d_ngtdm_strength_regression,agree,row+config,audit/ngtdm_3d_pyradiomics_vetting_report.md,audit/ngtdm_3d_golden_regen.md,matrix/ngtdm3d.md,"Snapshot drift guard only, recipe ngtdm3d.regression_ut_phantom; establishes no vetting (SPEC 1). The segmented ut_ phantom (ut_inten.nii + ut_mask57.nii, label 57) at NGTDM_GREYDEPTH=64, GREYDEPTH=64, NGTDM_RADIUS=1, ibsi=false -- a different fixture and a different config point from the oracle rows above, not a second assertion on them. At NGTDM_GREYDEPTH=64 the binning is MATLAB-style: the ROI's voxels take levels 1..64 and the rest of the bounding box level 0, and since 0 is then among the levels the family lifts every level by one, the background to 1. A background voxel is no centre, but it is a grey level of the matrix and counts towards its neighbours' neighbourhood means; no reference tool reproduces that, which is why this fixture carries no oracle claim. Pinned at full precision in test_3d_ngtdm_regression.h at rel=1e-9; regenerate with runAllTests --gtest_filter=*3D_NGTDM_DUMP_REGRESSION*. The family's oracle assertions are the ngtdm3d.pyradiomics_binwidth1 and ngtdm3d.pyradiomics_binwidth1_r2 rows. Evidence: tests/vetting/audit/ngtdm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lae_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_gln_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glnn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_szn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SZNN_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sznn_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZP_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zp_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_GLV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_glv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZV_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_zv_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." 3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-3,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." 3D,glszm,3GLSZM_ZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=2e-3,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." 3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_ZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." -3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." -3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." -3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: the background is intensity 0 here and bin 1 under MATLAB binning, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." -3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." -3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. The intercept is doing real work at radiomics binning, where to_grayscale_radiomix divides by (max - min); it is not conditioned on that, so it also discards the two schemes that would have answered. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-6,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md. 3GLSZM_ZE alone is banded at rel=1e-6 rather than the exact tier: it is the family's only logarithm, and fast_log10() evaluates its float polynomial with fused multiply-adds under clang on arm64 and without them under MSVC on x86-64, so a pin taken on one platform moves on the other. Measured on this same phantom, 3GLRLM_RE moves by 1.06e-9 between the two while every non-logarithm feature moves by ~1e-16; test_3d_glrlm_regression.h carries the identical carve-out." +3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_HGLZE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_hglze_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_salgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_SAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_sahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LALGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lalgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_bincount20,rel=1e-9,agreed,bench_compat_liver_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on the compat phantom (bench_compat_liver_3d, label 1), recipe glszm3d.pyradiomics_bincount20. Nyxus' GLSZM_GREYDEPTH=-20 and PyRadiomics' binCount=20 produce the same twenty levels, and both sides gather zones over the full 26-voxel neighbourhood, so no convention separates them: the measured residual is within a few ULP (worst 1.19e-15) on fifteen of the sixteen features, asserted at rel=1e-9. 3GLSZM_ZE is the exception at rel=1e-3, its residual 1.9e-4, because Nyxus takes the only logarithm in the family through fast_log10() -- a documented fast path, banded rather than reported. Backed by the SIXTEEN SCALARS AND THE MATRIX THEY CONTRACT: test_3d_glszm_matrix_pyradiomics reads the size-zone matrix off the feature object calculate() filled -- all 186 non-empty cells of the 20x634 table, its Ng/Ns/Nz/Np, the width and height it was allocated at, and a count proving no cell outside them is populated -- against PyRadiomics' own P_glszm array, read through its jvector because PyRadiomics deletes the columns for zone sizes nothing occupies. A defect planted in the production fill loop alone fails it, naming the level and the size, while all sixteen scalars still pass. The family's other assertions are their own rows: glszm3d.pyradiomics_ibsi_gapped, glszm3d.regression_ut_phantom and glszm3d.regression_ut_phantom_nobinning. tests/python/test_nyxus.py::test_3d_glszm_compatibility asserts these same goldens through the Python API; neither is this row's assertion. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md; generator tests/vetting/oracles/gen_glszm3d_pyradiomics.py." +3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_ibsi_gapped,rel=1e-9,agreed,bench_cube3_gapped_levels,TEST_NYXUS.TEST_3D_GLSZM_IBSI_GAPPED_PYRADIOMICS,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_ibsi_gapped_pyradiomics,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Vetted against PyRadiomics 3.0.1 GLSZM on bench_cube3_gapped_levels, recipe glszm3d.pyradiomics_ibsi_gapped: a 3x3x3 literal carrying grey levels 1, 3 and 5 with 2 and 4 absent, read by Nyxus at IBSI=true and by PyRadiomics at binWidth=1. This is the only configuration that reaches calculate()'s IBSI-only expressions -- row = zone.first-1 and Ng = max(I) -- and the only fixture on which they are distinguishable from the ones beside them, since a level's position and the level itself are different numbers here. Both sides report Ng = 5 for three occupied levels. Fifteen features agree exactly; 3GLSZM_ZE is banded at rel=2e-3 on a measured residual of 1.1e-3, the same fast_log10 path costing more on a six-zone matrix than on the phantom's 860. The size-zone matrix is pinned cell by cell off the feature object as well. test_3d_glszm_ibsi_equals_no_binning_mechanics measures that this configuration and GLSZM_GREYDEPTH=0 produce bit-identical values and matrices, which is why tests/vetting/matrix/glszm3d.md carries one cell for the two. Evidence: tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_LAHGLE_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_lahgle_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom on bench_ut57_3d (label 57) at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=64 -- MATLAB-style binning, the configuration the retired 3D coverage sweep ran every 3D family at on this phantom. Establishes no vetting (SPEC 1): the values are Nyxus' own %.17g output and catch movement only. PyRadiomics has no MATLAB-binning counterpart, so this configuration has no oracle; the family's vetted rows are glszm3d.pyradiomics_bincount20 and glszm3d.pyradiomics_ibsi_gapped. Re-pinned in this pass: the file held sixteen functions that test_all.cc had never called, and its old pins reproduced at no configuration in the tree. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_ut_phantom_nobinning,rel=1e-9,,bench_ut57_3d,TEST_NYXUS.TEST_3D_GLSZM_NO_BINNING_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_no_binning_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_ut_phantom_nobinning on bench_ut57_3d (label 57) at GLSZM_GREYDEPTH=0 -- no binning at all, which --coarseGrayDepth=0 or 3glszm/greydepth=0 selects; a run that names neither bins at the coarse grey depth, 64. It is a configuration of its own rather than a variant of the other two: no binning keeps the raw intensities where MATLAB binning scales [0, max] onto 1..64, so it is a different quantity and not a coarser one. Establishes no vetting (SPEC 1). Sixteen numeric pins under one gtest case, because one phantom read answers all sixteen and the matrix at this setting is as wide as the phantom's largest raw level. The same setting does have an oracle on a fixture small enough to carry one: glszm3d.pyradiomics_ibsi_gapped. test_3d_glszm_default_greydepth_mechanics separately asserts that compile_feature_settings() delivers the coarse grey depth, 64, when nothing names the family's binning, and test_3d_glszm_constant_roi_regression pins the soft-NaN a constant-intensity ROI comes back as -- a known defect, carried in tests/vetting/matrix/glszm3d.md as a VALID-prod-only cell. Evidence: tests/vetting/audit/glszm_3d_golden_regen.md." +3D,glszm,3GLSZM_SAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sae_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_LAE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lae_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lae_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_GLN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLN,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_gln_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_gln_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_GLNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLNN,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_glnn_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glnn_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_SZN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZN,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_szn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_szn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_SZNN,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SZNN,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sznn_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sznn_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_ZP,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZP,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zp_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zp_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_GLV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_GLV,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_glv_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_glv_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_ZV,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_ZV,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics;test_3d_glszm_zv_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_zv_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_ZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_ze_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_ze_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,2,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LGLZE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lglze_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_HGLZE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_HGLZE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_hglze_pyradiomics;test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_hglze_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_SALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SALGLE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_salgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_salgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_SAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_SAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_sahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_no_binning_regression;test_3d_glszm_sahgle_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_LALGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LALGLE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lalgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lalgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glszm,3GLSZM_LAHGLE,regression,,glszm3d.regression_constant_roi,abs=1e-9,,bench_cube2_constant,TEST_NYXUS.TEST_3D_GLSZM_CONSTANT_ROI_REGRESSION,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",test_3d_glszm_constant_roi_regression,agree,row+config,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"Snapshot drift guard only, recipe glszm3d.regression_constant_roi on bench_cube2_constant -- a 2x2x2 volume of one non-background intensity at GREYDEPTH=64, IBSI=false, GLSZM_GREYDEPTH=0, with the soft-NaN sentinel set to -98765 so a zero-filled buffer cannot satisfy the assertion. Establishes no vetting (SPEC 1). What it pins is a known defect rather than an endorsed value: a constant-intensity ROI is fully populated and has sixteen finite features over it -- on this cube SAE = 1/64, LAE = 64, ZE = 0, GLV = 0, ZP = 1/8 -- and calculate()'s unconditional aux_min == aux_max intercept returns the sentinel for all sixteen instead. It is not conditioned on any binning scheme, so it discards every scheme's answer: at radiomics binning TextureFeature::fixed_bin_number puts a range of zero width into one bin, so a one-level matrix lies beneath it there too. Narrowing it changes a public feature's output on a reachable input, so it is src work on its own branch and this row pins the current behaviour rather than endorsing it -- these sixteen assertions are what fail the day it is narrowed. Banded at SPEC 7's absolute exact tier; the assertion is ASSERT_EQ, bit-exact against the sentinel, because no arithmetic runs below the intercept. The same GLSZM_GREYDEPTH on a phantom is glszm3d.regression_ut_phantom_nobinning, which says nothing about this path. Recorded in tests/vetting/matrix/glszm3d.md; evidence tests/vetting/audit/glszm_3d_pyradiomics_vetting_report.md." +3D,glszm,3GLSZM_LAHGLE,vetted,pyradiomics,glszm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glszm_ibsi_gapped_pyradiomics;test_3d_glszm_lahgle_pyradiomics;test_3d_glszm_volmin_pyradiomics,test_3d_glszm_constant_roi_regression;test_3d_glszm_lahgle_regression;test_3d_glszm_no_binning_regression,test_3d_glszm_compatibility;test_3d_glszm_default_greydepth_mechanics;test_3d_glszm_ibsi_equals_no_binning_mechanics,3,3,"the size-zone matrix all sixteen features contract is pinned cell by cell as well, read off the feature object calculate() filled, in test_3d_glszm_matrix_pyradiomics | also asserted by test_3d_glszm_compatibility (kind is neither oracle nor regression) | also asserted by test_3d_glszm_default_greydepth_mechanics (kind is neither oracle nor regression) | also asserted by test_3d_glszm_ibsi_equals_no_binning_mechanics (kind is neither oracle nor regression)",,agree,feature,audit/glszm_3d_pyradiomics_vetting_report.md,audit/glszm_3d_golden_regen.md,matrix/glszm3d.md,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glszm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. Asserted at rel=1e-9 by test_3d_glszm_volmin_pyradiomics in tests/python/test_3d_glszm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLSZM_ZE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glszm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glrlm,3GLRLM_SRE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_sre_pyradiomics,test_3d_glrlm_sre_grey64_regression;test_3d_glrlm_sre_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_LRE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_lre_pyradiomics,test_3d_glrlm_lre_grey64_regression;test_3d_glrlm_lre_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_GLN,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_gln_pyradiomics,test_3d_glrlm_gln_grey64_regression;test_3d_glrlm_gln_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." @@ -1047,22 +1127,37 @@ dim,family,feature,claim_status,claim_oracle,claim_recipe,claim_tolerance,claim_ 3D,glrlm,3GLRLM_SRHGLE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_srhgle_pyradiomics,test_3d_glrlm_srhgle_grey64_regression;test_3d_glrlm_srhgle_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_LRLGLE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_lrlgle_pyradiomics,test_3d_glrlm_lrlgle_grey64_regression;test_3d_glrlm_lrlgle_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." 3D,glrlm,3GLRLM_LRHGLE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_lrhgle_pyradiomics,test_3d_glrlm_lrhgle_grey64_regression;test_3d_glrlm_lrhgle_regression,,2,2,,,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20, PER DIRECTION: test_3d_glrlm_pyradiomics.h compares all 13 directional values of this feature against PyRadiomics' own per-angle values (glrlm_3d_pyradiomics_ref_vals_by_angle), not their average - on this fixture the average agrees to 1e-16 even when the directions are paired up wrongly, so averaging cannot vet them. Measured residual <= 5.5e-16 per direction. Angle slots line up one-to-one with PyRadiomics because both order angles (dz,dy,dx); goldens and that mapping from gen_glrlm3d_pyradiomics.py. test_3d_glrlm_regression.h pins Nyxus' own values on the ut_ phantom at a different bin count and claims no oracle." -3D,glrlm,3GLRLM_SRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_sre_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_LRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_lre_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_GLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_gln_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_GLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_glnn_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_RLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_rln_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_RLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_rlnn_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_RP_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_rp_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,registry read oracle=mirp while the base row read oracle=pyradiomics for the same quantity; no mirp run for 3D GLRLM has ever existed in the tree | also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_GLV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_glv_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_RV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_rv_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_SRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_sre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_SRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_sre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_LRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_LRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_GLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_gln_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_GLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_gln_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_GLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_glnn_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_GLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_glnn_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_RLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rln_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_RLN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rln_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_RLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rlnn_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_RLNN_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rlnn_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_RP_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rp_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,registry read oracle=mirp while the base row read oracle=pyradiomics for the same quantity; no mirp run for 3D GLRLM has ever existed in the tree | also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_RP_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rp_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,registry read oracle=mirp while the base row read oracle=pyradiomics for the same quantity; no mirp run for 3D GLRLM has ever existed in the tree | also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_GLV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_glv_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_GLV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_glv_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_RV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rv_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_RV_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_rv_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." 3D,glrlm,3GLRLM_RE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=2e-3,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_re_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,"same mirp mislabel as 3GLRLM_RP_AVE, and the same log tolerance as 3GLRLM_RE | also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression)",,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual 6.2e-4. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle. 3GLRLM_RE is the family's only sum over logarithms and Nyxus evaluates it through fast_log10 (helpers.h), a float-precision log2 approximation, against PyRadiomics' double numpy.log2 - that is the band, not a definitional difference." -3D,glrlm,3GLRLM_LGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_lglre_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_HGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_hglre_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_SRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_srlgle_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_SRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_srhgle_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_LRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_lrlgle_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." -3D,glrlm,3GLRLM_LRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics,test_3d_glrlm_lrhgle_ave_grey64_regression,test_3d_glrlm_compatibility,1,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_LGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lglre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_LGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lglre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_HGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_hglre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_HGLRE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_hglre_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_SRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_srlgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_SRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_srlgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_SRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_srhgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_SRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_srhgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_LRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lrlgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_LRLGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lrlgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." +3D,glrlm,3GLRLM_LRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_bincount20,rel=1e-9,agreed,,,,,audit,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lrhgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on the compat phantom, recipe glrlm3d.pyradiomics_bincount20. PyRadiomics reports one value per feature over its whole direction set, which is this *_AVE aggregation over the 13 3D angles; the assertion reads the stored *_AVE feature rather than recomputing it. The 13 directional values of the base feature are asserted separately and per direction. Measured residual <= 5.5e-16. test_3d_glrlm_regression.h additionally pins this feature at the grey64 profile (GLRLM_GREYDEPTH=+64), a second configuration nothing else exercises; that pin claims no oracle." +3D,glrlm,3GLRLM_LRHGLE_AVE,vetted,pyradiomics,glrlm3d.pyradiomics_volmin_bincount8,rel=1e-9,agreed,bench_volmin_3d,,,,in-tree,pyradiomics,test_3d_glrlm_ave_pyradiomics;test_3d_glrlm_volmin_pyradiomics,test_3d_glrlm_lrhgle_ave_grey64_regression,test_3d_glrlm_compatibility,2,1,also asserted by test_3d_glrlm_compatibility (kind is neither oracle nor regression),,agree,feature,audit/glrlm_3d_pyradiomics_vetting_report.md,audit/glrlm_3d_golden_regen.md,,"vetted vs PyRadiomics 3.0.1 on bench_volmin_3d, recipe glrlm3d.pyradiomics_volmin_bincount8: Nyxus coarse_gray_depth=-8, PyRadiomics-style binning (IBSI's fixed bin number over the ROI's own [min, max]), against PyRadiomics binCount=8, label 1, no resampling, weightingNorm=None, force2D=False -- each tool discretising for itself. The ROI holds the volume's lowest intensity, which Nyxus stores as 0, the value the background cells of its bounding box hold; under this binning those voxels are the ROI's bin 1. The same table holds on the control bench_volmin_ctrl_3d, whose ROI is stored without a 0, and both run in RAM and out of core (an OME-TIFF Z-stack streamed at ram_limit=0). A family that bins a stored 0 to level 0 reads those voxels as background, or shifts every level by one, and parts from the table on bench_volmin_3d while it still holds on the control. PyRadiomics reports one value over its 13 directions, which is this *_AVE aggregation. Asserted at rel=1e-9 by test_3d_glrlm_volmin_pyradiomics in tests/python/test_3d_glrlm_pyradiomics.py, a pytest case, so test_name is empty; the logarithmic 3GLRLM_RE_AVE carries Nyxus' fast_log10 approximation and so stays out of the table. tests/vetting/oracles/gen_glrlm3d_pyradiomics.py re-verifies every pin at rel 1e-12 and that PyRadiomics gives the control the same values." IMQ,imq,FOCUS_SCORE,vetted,opencv,imq.laplacian_ksize1_zeropad,abs=1e-9,agreed,bench_imq_quality_roi,TEST_NYXUS.TEST_IMQ_FOCUS_SCORE_OPENCV,,,audit,opencv,test_imq_focus_score_opencv,,test_imq_focus_score_out_of_core_invariant;test_imq_local_focus_score_thin_roi_mechanics,1,0,,test_imq_focus_score_opencv,agree,row,audit/imq_opencv_vetting_report.md,audit/imq_golden_regen.md,matrix/imq.md,"vetted vs OpenCV cv2.Laplacian(roi, CV_64F, ksize=1, BORDER_CONSTANT).var() = 34.956597222222221 (cv2 4.13.0, gen_imq_opencv.py), the Pech-Pacheco et al. (2000) variance-of-the-Laplacian focus measure. The generator asserts cv2's filtered image equals Nyxus' laplacian() cell for cell before comparing any scalar, so the convolution is proved and only the variance step is under test; Nyxus reproduces the scalar to 7.1e-15 absolute (2.0e-16 relative), which is summation order alone. Band is SPEC 7's exact tier, an ABSOLUTE 1e-9 via ASSERT_NEAR. SCOPE: ksize=1, the only kernel calculate() selects. laplacian()'s ksize>1 kernel is cv2.Laplacian's ksize=3 aperture exactly: both stencils are pinned from cv2's unit-spike response in test_imq_opencv.h (TEST_IMQ_FOCUS_SCORE_KERNEL_PER_CALL_OPENCV) and the generator asserts the ksize=3 filtered fixture equal to cv2's cell for cell. The out-of-core path shares the in-RAM scoring code and is held bit-equal to it by test_imq_invariant.h (an invariant, not vetting). Report: audit/imq_opencv_vetting_report.md; matrix/imq.md." IMQ,imq,LOCAL_FOCUS_SCORE,vetted,opencv,imq.laplacian_ksize1_zeropad,abs=1e-9,agreed,bench_imq_quality_roi,TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_OPENCV,,,audit,analytic;opencv,test_imq_local_focus_score_all_tiles_analytic;test_imq_local_focus_score_each_tile_analytic;test_imq_local_focus_score_opencv,,test_imq_focus_score_out_of_core_invariant;test_imq_local_focus_score_remainder_mechanics;test_imq_local_focus_score_smallest_tiled_roi_mechanics;test_imq_local_focus_score_thin_roi_mechanics,3,0,"opencv covers each tile's Laplacian variance and their mean; the tile grid is Nyxus' own definition, reproduced in the generator and pinned tile by tile by the analytic row. See not_covered.md section E",test_imq_local_focus_score_opencv,agree,row,audit/imq_opencv_vetting_report.md,audit/imq_golden_regen.md,matrix/imq.md,"vetted vs OpenCV: the mean of cv2.Laplacian(tile, CV_64F, ksize=1, BORDER_CONSTANT).var() over the 2x2 grid of 4x6 tiles get_local_focus_score() cuts the 8x12 fixture into at scale=2 = 28.341145833333336 (cv2 4.13.0, gen_imq_opencv.py, which asserts the tile count and prints each tile's score). Nyxus reproduces it to 7.1e-15 absolute (2.5e-16 relative); band is SPEC 7's exact tier, an ABSOLUTE 1e-9 via ASSERT_NEAR. Negative control: the one-tile value a truncated y < height-M loop bound gives, 7.5763888888888902, is asserted to sit 73% away, so the pin tells the full tiling from the truncated one. Report: audit/imq_opencv_vetting_report.md; matrix/imq.md. ORACLE SPLIT (not_covered.md section E): OpenCV supplies each tile's Laplacian and population variance; the tile grid is Nyxus' own definition, reproduced in the generator and pinned tile by tile by the analytic row." IMQ,imq,LOCAL_FOCUS_SCORE,vetted,analytic,imq.local_focus_single_spike,abs=0,agreed,,TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_EACH_TILE_ANALYTIC;TEST_NYXUS.TEST_IMQ_LOCAL_FOCUS_SCORE_ALL_TILES_ANALYTIC,,,in-tree,analytic;opencv,test_imq_local_focus_score_all_tiles_analytic;test_imq_local_focus_score_each_tile_analytic;test_imq_local_focus_score_opencv,,test_imq_focus_score_out_of_core_invariant;test_imq_local_focus_score_remainder_mechanics;test_imq_local_focus_score_smallest_tiled_roi_mechanics;test_imq_local_focus_score_thin_roi_mechanics,3,0,"opencv covers each tile's Laplacian variance and their mean; the tile grid is Nyxus' own definition, reproduced in the generator and pinned tile by tile by the analytic row. See not_covered.md section E",test_imq_local_focus_score_all_tiles_analytic;test_imq_local_focus_score_each_tile_analytic,agree,row,audit/imq_opencv_vetting_report.md,audit/imq_golden_regen.md,matrix/imq.md,"vetted against a closed form, no generator: a single spike of height v clear of the tile edge has a ksize=1 Laplacian of -4v at the spike and +v at its four neighbours, so its tile scores exactly 20v^2/P and every all-zero tile scores 0. test_imq_analytic.h places the spike in each of the scale^2 = 4 tiles in turn on 8x12, 9x12, 8x13 and 9x13 ROIs (a 2x2 grid of 4x6 tiles in all four) and asserts 20*36/24/4 = 7.5 for every placement, and 4x that with a spike in every tile. Exact band: integer arithmetic, exact in double. Both side parities are needed: a y < height-M loop bound stops after the first tile on an even side but reaches the second on an odd one. Which pixels belong to no tile, and the soft-NaN an ROI no tile fits returns, are Nyxus conventions pinned as mechanics in test_imq_mechanics.h, not vetted. See matrix/imq.md." diff --git a/tests/vetting/report_output.md b/tests/vetting/report_output.md index d5868e637..a84f0a62b 100644 --- a/tests/vetting/report_output.md +++ b/tests/vetting/report_output.md @@ -32,11 +32,11 @@ regression: 121 invariant: 0 untested: 0 ## Verdicts -1074 of 1074 assertion rows agree with the tree. +1169 of 1169 assertion rows agree with the tree. | verdict | rows | meaning | |---|---:|---| -| `agree` | 1074 | the claim and the tree say the same thing | +| `agree` | 1169 | the claim and the tree say the same thing | ### How far each verdict reaches @@ -45,7 +45,7 @@ regression: 121 invariant: 0 untested: 0 | scope | rows | what was compared | |---|---:|---| -| `feature` | 533 | `test_name` is empty, so the tree was read for the feature and not for this row's own assertion | +| `feature` | 628 | `test_name` is empty, so the tree was read for the feature and not for this row's own assertion | | `row` | 318 | the case named in `test_name` asserts this feature, at this row's kind; its configuration is unchecked, the family declaring no recipe reader | | `row+config` | 223 | the case named in `test_name` asserts this feature at this `config_recipe` | @@ -73,7 +73,7 @@ that alone understates every family that corroborates. | 2D | radial | . | . | . | . | . | . | . | . | . | . | 3 | | 2D | zernike | 1 | . | . | . | . | . | . | . | . | . | . | | 3D | firstorder | . | . | . | . | . | 29 | . | . | 17 | . | 3 | -| 3D | glcm | . | . | . | . | . | . | . | . | 59 | . | . | +| 3D | glcm | 2 | . | . | . | . | . | . | . | 59 | . | . | | 3D | gldm | . | . | . | . | . | . | . | . | 14 | . | . | | 3D | gldzm | . | . | . | . | . | . | 16 | . | . | . | 2 | | 3D | glrlm | . | . | . | . | . | . | . | . | 32 | . | . | @@ -82,7 +82,7 @@ that alone understates every family that corroborates. | 3D | ngldm | . | . | . | . | . | . | 16 | . | . | . | 3 | | 3D | ngtdm | . | . | . | . | . | . | . | . | 5 | . | . | | IMQ | imq | 1 | 2 | . | . | . | . | . | 2 | . | . | 2 | -| | **all** | **41** | **9** | **2** | **181** | **20** | **95** | **208** | **2** | **272** | **127** | **121** | +| | **all** | **43** | **9** | **2** | **181** | **20** | **95** | **208** | **2** | **272** | **127** | **121** | ## By dimensionality From 8890f51667f55dde6a0ac480edfefde7e228cd53 Mon Sep 17 00:00:00 2001 From: Demian Vladi Date: Wed, 21 Oct 2026 08:26:28 -0700 Subject: [PATCH 3/3] ci: re-run CI after EPEL mirror failures on the wheel builds