[MINC-development] Unexpected value scaling with miget_real_value_hyperslab

Rick Hoge rick.hoge at linev.ca
Sun Jan 9 23:45:51 EST 2011


Thanks for the suggestion Andrew,

[...]

>>> Finally I found the function miget_volume_real_range(), which does return the actual min and max values.  However this is not really documented anywhere...
> 
> Ah good to see you found one of the functions you (might) need.  I
> think you are still being bitten by slice scaling though. In order to
> make sure that this is or isn't the case perhaps run the output file
> through something like mincreshape -signed -short (and then back
> again) to check this?

I tried a few permutations of mincreshape, including the above, but no matter what I tried the data values were mapped to span the whole valid range when loaded into an integer type.

> Jason gives a nice example of how to deal with slice scaling here:
> 
>   http://en.wikibooks.org/wiki/MINC/Tutorials/Programming04

I'd looked at this (and these tutorials are indeed very helpful), but the example was a bit different in that it shows a set of nested loops with miget_real_value at the core and setting the range values for each slice.  I just want to read the entire dataset into a single buffer, which I'd expect should be possible in one function call.  

> 
>> Playing around with ICV's the only other thing I've been able to do is to get the data values mapped into the 12-bit range 0 to 4095, which is still not the actual data range.
> 
> Again, I'll punt this is slice scaling biting you here.

As I'd mentioned, slice scaling is indeed turned on for the data in question, which were generated using dcm2mnc.  I'm not sure why this scaling would be applied to 12-bit numbers stored in short integer words in the DICOM file, as it does not add anything to the real dynamic range and could alter the original values.

> 
>> I realize that in some cases there can be an advantage to using the whole dynamic range of a given data type, but surely there is a way to preserve the original values?
> 
> In MINC1 there was never any magic to do this, you'd just do something
> like this (in the output file) to take a crack at it:
> 

Like you say, it was fairly simple using the MINC1 API.

[...]


> If you _really_ want to preserve values in a MINC file your best bet
> is to use something like a float. Yes, it takes more space but then
> that's somewhat cheap now.

I'm not so concerned about the disk space (although saving it is nice);  it's more a question of data integrity.  For MR quality assurance it's useful in a number of situations to be able to know the binary exact value that was stored on the scanner.  Also if the data were assigned integer values in some kind of labelling or lookup table scheme, a programmer would reasonably expect to be able to test for exact integer equality - this breaks down if the data are converted to float.  The really weird thing is that if I do load the data as float, the numbers appear to deviate from the original integer values by a decimal fraction that is quite significant.  For example if I use

miget_real_value_hyperslab(minc_volume, MI_TYPE_FLOAT, starts, counts, buffer)

to fill a buffer with float values from a file purported to contain unsigned short values, I get close to the correct numeric voxel values.  However the values all include a non-zero decimal fraction component, so that a voxel with a true value of 327 comes out as 326.74.  Maybe MINC2 has a new dithering feature?  :)  Before creating a panic I should triple check this, and post a small code fragment that demonstrates the phenomenon.

> MINC2 really needed a "integer" type or flag of some description to
> define a label volume but introducing it would have meant a world of
> pain adding special code to deal with this in all the other tools. In
> some cases the behavior would have been fairly arbitrary in any case.

I can certainly see the appeal of just deciding to always use float or doubles internally, but in some contexts it's nice to preserve the original data values.  However it's true that - in the case of fMRI - as soon as you motion-correct, smooth, etc. it becomes kind of silly to retain the data as integer.  Also virtually everything ever done in Matlab is treating everything as a double float.

A kind of kludgy workaround I came up with was to load the data as float, then round the voxel values, which appears to recover the original short ints.  

> Hope that helps.

It does - thanks!

Rick

> 
> 
> --
> Andrew Janke
> (a.janke at gmail.com || http://a.janke.googlepages.com/)
> Canberra->Australia    +61 (402) 700 883
> _______________________________________________
> MINC-development mailing list
> MINC-development at bic.mni.mcgill.ca
> http://www.bic.mni.mcgill.ca/mailman/listinfo/minc-development

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.bic.mni.mcgill.ca/pipermail/minc-development/attachments/20110109/0c432b60/attachment.htm>


More information about the MINC-development mailing list