[MINC-development] minc2 bug

Jason Lerch jason at phenogenomics.ca
Wed Jul 28 12:17:17 EDT 2010


  Greetings all,

found a minc2 API bug, I think. The symptoms:

miget_real_value and miget_real_value_hyperslab don't return the same 
value (which they should) if the underlying data is float or double (and 
there's some slice scaling? Not sure about the last part).

The likely cause:

miget_real_value blindly does voxel to real conversion regardless of the 
underlying data type (float and double don't need this conversion, if my 
minc foo is up to date).

Here's a bit of code to test this:

====

#include <minc2.h>
#include <stdio.h>

int main(int argc, char **argv) {
   unsigned long location[3];
   unsigned long count[3];
   double test_voxel, test_hyper, test_voxel_value;
   int result;
   mihandle_t hvol;
   mitype_t data_type;

   location[0] = 50;
   location[1] = 50;
   location[2] = 50;

   count[0] = 1;
   count[1] = 1;
   count[2] = 1;

   result = miopen_volume(argv[1], MI2_OPEN_READ, &hvol);
   if (result != MI_NOERROR) {
     fprintf(stderr, "Error opening file %s \n", argv[1]);
     exit(1);
   }

   result = miget_real_value_hyperslab(hvol,
                       MI_TYPE_DOUBLE,
                       location,
                       count,
&test_hyper);
   if (result != MI_NOERROR) {
     fprintf(stderr, "Error getting voxel from hyperslab\n");
     exit(1);
   }
   result = miget_real_value(hvol, location, 3, &test_voxel);
   if (result != MI_NOERROR) {
     fprintf(stderr, "Error getting voxel using miget_real_value\n");
     exit(1);
   }
   result = miget_voxel_value(hvol, location, 3, &test_voxel_value);
   if (result != MI_NOERROR) {
     fprintf(stderr, "Error getting voxel using miget_voxel_value\n");
     exit(1);
   }


   result = miget_data_type(hvol, &data_type);
   if (result != MI_NOERROR) {
     fprintf(stderr, "Error getting data type\n");
     exit(1);
   }
   if (data_type == MI_TYPE_FLOAT || data_type == MI_TYPE_DOUBLE) {
     printf("Float or double found - trouble ahead?\n");
   }
   else {
     printf("Something other than float - clear sailing?\n");
   }

   printf("get_voxel value: %f\nget_hyperslab value: %f\nRaw Voxel value 
%f:\n", test_voxel, test_hyper, test_voxel_value);
   return(0);
}

===

And here's a potential fix: in libsrc2/convert.c, replace:

int
miget_real_value(mihandle_t volume,
                  const unsigned long coords[],
                  int ndims,
                  double *value_ptr)
{
     double voxel;
     int result;

     result = miget_voxel_value(volume, coords, ndims, &voxel);
     if (result != MI_NOERROR) {
         return (result);
     }
     miconvert_voxel_to_real(volume, coords, ndims, voxel, value_ptr);
     return (MI_NOERROR);
}

with this:

int
miget_real_value(mihandle_t volume,
                  const unsigned long coords[],
                  int ndims,
                  double *value_ptr)
{

     double voxel;
     int result;
     mitype_t data_type;

     result = miget_voxel_value(volume, coords, ndims, &voxel);
     if (result != MI_NOERROR) {
         return (result);
     }
     result = miget_data_type(volume, &data_type);
     if (result != MI_NOERROR) {
         return (result);
     }

     if (data_type == MI_TYPE_FLOAT || data_type == MI_TYPE_DOUBLE) {
       *value_ptr = voxel;
     }
     else {
       miconvert_voxel_to_real(volume, coords, ndims, voxel, value_ptr);
     }
     return (MI_NOERROR);
}

Somebody with more minc2 knowledge should check this - it's also 
possible that the fix should be in miconvert_voxel_to_real instead.

Jason



More information about the MINC-development mailing list