Skip to content

Disagreement between miget_real_value and miget_real_value_hyperslab #108

@cfhammill

Description

@cfhammill

Typically in RMINC we read data in using miget_real_value_hyperslab. However one of our functions, mincGetVoxel uses miget_real_value. I would have assumed that these two functions would agree on any particular voxel's real value, but that doesn't seem to be the case at least for double precision volumes. Internally miget_real_value uses mirw_hyperslab_raw which does no conversion on the value, and then post-hoc calls miconvert_voxel_to_real. Whereas miget_real_value_hyperslab calls mirw_hyperslab_icv which does its own, apparently more complicated scaling internally. So I suspect that miconvert_voxel_to_real is missing something relevant for the rescaling.

Here's a sample C program illustrating the problem

test-miget-real-voxel.c
#include <minc2.h>
#include <stdio.h>
int main(int argc, char** argv){
  char* file=argv[1];
  misize_t location[3];
  misize_t count[3];
  mihandle_t hvol;
  int result;
  int i;
  double single;
  double slab;
  for(i = 0; i < 3; i++){
    location[i] = 50;
    count[i] = 1;
  }
  result = miopen_volume(file,
                         MI2_OPEN_READ, &hvol);
  if (result != MI_NOERROR) {
    printf("Error opening input file: %s.\n", file);
    return 1;
  }
  result = miget_real_value(hvol, location, 3, &single);
  printf("Getting a single value returns: %f.\n", single);
  result = miget_real_value_hyperslab(hvol, MI_TYPE_DOUBLE, location, count, &slab);
  printf("Getting a size 1 slab returns: %f.\n", slab);
  return 0;
}

An easy way to test is to convert the icbm average to unsigned double

mincresample -2 -double mni_icbm152_t1_tal_nlin_sym_09a.mnc mni_icbm152_t1_tal_nlin_sym_09a_signed_double.mnc

Then compile and run the above program to check the difference, on my machine I get

Getting a single value returns: 15.561608.
Getting a size 1 slab returns: 17.435906.

This was noticed by one of our users getting the expected answer when using mincAnova which uses miget_real_value_hyperslab internally, but a very different answer when plucking individual voxels with mincGetVoxel which uses miget_real_value

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions