nifti2_data_format > NIFTI-2 proposal (initial discussion)
Showing 1-25 of 26 posts
Feb 28, 2011 04:02 PM | Mark Jenkinson
NIFTI-2 proposal (initial discussion)
[size= medium]A 64-bit update to the NIfTI
format
[/size]
The NIfTI committee are proposing the creation of a NIfTI-2 format that is a very simple extension of the current NIfTI-1 format, but updated to allow 64-bit storage and addressing for large images and matrices.
It is intended that this format:
- will enable the storage of large images and matrices, with all dimensions being coded by 64-bit integers rather than the current limitation of 16-bit signed integers (which currently gives a restrictive 32767 size limit in each dimension)
- will be very simple to implement and update software (a couple of hours coding or less generally)
- contains the same information as a NIfTI-1 file (no new fields and all current fields still retained)
- will support the existing file formats and naming: a .nii single-file, a .hdr/.img file-pair and their gzipped versions
- has a very simple test (see below) to determine if the file is NIfTI-1 or NIfTI-2
- does not replace NIfTI-1 in the short term but is supported alongside it
Comments
This announcement is intended for public comment.
Please post any comments on this NIfTI-2 proposal to the NITRC discussion list (www.nitrc.org/forum/forum.php?forum_id=1941)
We ask that comments relating to larger-scale changes and requests for other types of format change be posted instead to a separate NITRC discussion list for more advanced neuroimaging formats (www.nitrc.org/forum/forum.php?forum_id=1942)
Supporting software
- AFNI, BrainVoyager, Caret, Connectome Workbench, Fiswidgets, FreeSurfer, FSL, ITK, LONI-DIRAC, MRIcron, NiBabel and SPM have all agreed to support the NIfTI-2 version in their upcoming releases, but that NIfTI-1 will remain a default output, or a configurable default, in the short-term
- the sourceforge supporting libraries in niftilib will be updated so that they seemlessly support both NIfTI-1 and NIfTI-2
- conversion utilities to and from NIfTI-1 will be made available via sourceforge as well as in some of the software packages mentioned above
Changes to the header
The changes to the NIfTI header structure are the following:
- short dim[8] becomes int64_t dim[8]
- float intent_p1 becomes double intent_p1
- float intent_p2 becomes double intent_p2
- float intent_p3 becomes double intent_p3
- float pixdim[8] becomes double pixdim[8]
- float vox_offset becomes int64_t vox_offset
- float scl_slope becomes double scl_slope
- float scl_inter becomes double scl_inter
- float cal_max becomes double cal_max
- float cal_min becomes double cal_min
- float slice_duration becomes double slice_duration
- float toffset becomes double toffset
- float quatern_b becomes double quatern_b
and similarly for quatern_c, quatern_d, qoffset_x, qoffset_y, qoffset_z
- float srow_x[4] becomes double srow_x[4]
and similarly for srow_y[4], srow_z[4]
- char magic[4] becomes char magic[8]
- char unused_str[12] is added after char magic[8]
The order, size and type of all other fields remains unchanged.
The sizeof_hdr must store 556 for a NIfTI-2 file instead of 348 for NIfTI-1.
Extension information is still held in the first 4 bytes after this header (bytes 557-560) in the same way as in NIfTI-1.
Note that the total block size of 560 (header + 4 bytes) retains the 16-byte alignment in NIfTI-1 (348+4=352), as needed for convenient memory-mapping.
The changes of float to double are generally made to allow for more accurate mapping of intensities or indices when dealing with very large arrays, and unused_str is added to ensure the 16-byte alignment holds.
Compatibility
This format is not, and cannot be, bit-wise compatible with the previous NIfTI-1 (or ANALYZE) formats and so will not work with existing NIfTI-1 software directly. In the short term this can be solved via conversion utilities. A NIfTI-2 image will not be recognised as a valid NIfTI-1 image by existing software and so no incorrect processing or analyses should occur. In the longer term most code should be very easily converted to work with both NIfTI-2 and NIfTI-1 by using the updated sourceforge libraries or making equivalent changes internally. The change in format is intentionally very minimal and should be very easy to code.
Determining the NIfTI version
The following pseudo-code shows how a file can be tested to see: (a) if it is a NIfTI image file, (b) what version of NIfTI it is, and (c) whether byte-swapping is required.
read in the first 4 bytes from the file
let d = the content of these bytes, formatted as a 32-bit int
if (d==348) then it is a NIfTI-1 file, no byte-swapping required
else if (swap_4bytes(d)==348) then it is a NIfTI-1 file, but with byte-swapping required
else if (d==556) then it is a NIfTI-2 file, no byte-swapping required
else if (swap_4bytes(d)==556) then it is a NIfTI-2 file, but with byte-swapping required
else it is not a valid NIfTI file
if it passed the above then read in the remaining 344 or 552 bytes of the header into the appropriate NIfTI-1 or NIfTI-2 struct
double-check this is truly a valid NIfTI file by looking at dim[0] (should be between 0 and 7) and magic[] which should contain "ni1" or "n+1" followed by \0 for NIfTI-1, and "ni2" or "n+2" followed by \0 and 4 extra signature bytes for NIfTI-2
Magic Signature
The magic string is expanded to 8 bytes with the first 4 bytes containing ones of the strings "ni2" or "n+2", terminated with \0. The next four bytes form a magic signature much the same as used by the PNG format (http://www.libpng.org/pub/png/pngintro.h...), to detect for file transfer errors involving newline characters. The extra four bytes are the same as the last four in the PNG format - that is: \r \n \032 \n (0D 0A 1A 0A)
The magic string will have a different offset from the start of the file in NIfTI-1 and NIfTI-2 (344 and 536 bytes respectively).
Timeline
Barring any unknown unknowns or unforseeable unforseen problems, it is intended to begin rolling out this format in practice in March-April 2011. Example datasets will also be provided soon.
[/size]
The NIfTI committee are proposing the creation of a NIfTI-2 format that is a very simple extension of the current NIfTI-1 format, but updated to allow 64-bit storage and addressing for large images and matrices.
It is intended that this format:
- will enable the storage of large images and matrices, with all dimensions being coded by 64-bit integers rather than the current limitation of 16-bit signed integers (which currently gives a restrictive 32767 size limit in each dimension)
- will be very simple to implement and update software (a couple of hours coding or less generally)
- contains the same information as a NIfTI-1 file (no new fields and all current fields still retained)
- will support the existing file formats and naming: a .nii single-file, a .hdr/.img file-pair and their gzipped versions
- has a very simple test (see below) to determine if the file is NIfTI-1 or NIfTI-2
- does not replace NIfTI-1 in the short term but is supported alongside it
Comments
This announcement is intended for public comment.
Please post any comments on this NIfTI-2 proposal to the NITRC discussion list (www.nitrc.org/forum/forum.php?forum_id=1941)
We ask that comments relating to larger-scale changes and requests for other types of format change be posted instead to a separate NITRC discussion list for more advanced neuroimaging formats (www.nitrc.org/forum/forum.php?forum_id=1942)
Supporting software
- AFNI, BrainVoyager, Caret, Connectome Workbench, Fiswidgets, FreeSurfer, FSL, ITK, LONI-DIRAC, MRIcron, NiBabel and SPM have all agreed to support the NIfTI-2 version in their upcoming releases, but that NIfTI-1 will remain a default output, or a configurable default, in the short-term
- the sourceforge supporting libraries in niftilib will be updated so that they seemlessly support both NIfTI-1 and NIfTI-2
- conversion utilities to and from NIfTI-1 will be made available via sourceforge as well as in some of the software packages mentioned above
Changes to the header
The changes to the NIfTI header structure are the following:
- short dim[8] becomes int64_t dim[8]
- float intent_p1 becomes double intent_p1
- float intent_p2 becomes double intent_p2
- float intent_p3 becomes double intent_p3
- float pixdim[8] becomes double pixdim[8]
- float vox_offset becomes int64_t vox_offset
- float scl_slope becomes double scl_slope
- float scl_inter becomes double scl_inter
- float cal_max becomes double cal_max
- float cal_min becomes double cal_min
- float slice_duration becomes double slice_duration
- float toffset becomes double toffset
- float quatern_b becomes double quatern_b
and similarly for quatern_c, quatern_d, qoffset_x, qoffset_y, qoffset_z
- float srow_x[4] becomes double srow_x[4]
and similarly for srow_y[4], srow_z[4]
- char magic[4] becomes char magic[8]
- char unused_str[12] is added after char magic[8]
The order, size and type of all other fields remains unchanged.
The sizeof_hdr must store 556 for a NIfTI-2 file instead of 348 for NIfTI-1.
Extension information is still held in the first 4 bytes after this header (bytes 557-560) in the same way as in NIfTI-1.
Note that the total block size of 560 (header + 4 bytes) retains the 16-byte alignment in NIfTI-1 (348+4=352), as needed for convenient memory-mapping.
The changes of float to double are generally made to allow for more accurate mapping of intensities or indices when dealing with very large arrays, and unused_str is added to ensure the 16-byte alignment holds.
Compatibility
This format is not, and cannot be, bit-wise compatible with the previous NIfTI-1 (or ANALYZE) formats and so will not work with existing NIfTI-1 software directly. In the short term this can be solved via conversion utilities. A NIfTI-2 image will not be recognised as a valid NIfTI-1 image by existing software and so no incorrect processing or analyses should occur. In the longer term most code should be very easily converted to work with both NIfTI-2 and NIfTI-1 by using the updated sourceforge libraries or making equivalent changes internally. The change in format is intentionally very minimal and should be very easy to code.
Determining the NIfTI version
The following pseudo-code shows how a file can be tested to see: (a) if it is a NIfTI image file, (b) what version of NIfTI it is, and (c) whether byte-swapping is required.
read in the first 4 bytes from the file
let d = the content of these bytes, formatted as a 32-bit int
if (d==348) then it is a NIfTI-1 file, no byte-swapping required
else if (swap_4bytes(d)==348) then it is a NIfTI-1 file, but with byte-swapping required
else if (d==556) then it is a NIfTI-2 file, no byte-swapping required
else if (swap_4bytes(d)==556) then it is a NIfTI-2 file, but with byte-swapping required
else it is not a valid NIfTI file
if it passed the above then read in the remaining 344 or 552 bytes of the header into the appropriate NIfTI-1 or NIfTI-2 struct
double-check this is truly a valid NIfTI file by looking at dim[0] (should be between 0 and 7) and magic[] which should contain "ni1" or "n+1" followed by \0 for NIfTI-1, and "ni2" or "n+2" followed by \0 and 4 extra signature bytes for NIfTI-2
Magic Signature
The magic string is expanded to 8 bytes with the first 4 bytes containing ones of the strings "ni2" or "n+2", terminated with \0. The next four bytes form a magic signature much the same as used by the PNG format (http://www.libpng.org/pub/png/pngintro.h...), to detect for file transfer errors involving newline characters. The extra four bytes are the same as the last four in the PNG format - that is: \r \n \032 \n (0D 0A 1A 0A)
The magic string will have a different offset from the start of the file in NIfTI-1 and NIfTI-2 (344 and 536 bytes respectively).
Timeline
Barring any unknown unknowns or unforseeable unforseen problems, it is intended to begin rolling out this format in practice in March-April 2011. Example datasets will also be provided soon.
Feb 28, 2011 04:02 PM | Chris Rorden
RE: NIFTI-2 proposal
This sounds pretty straight forward. I am happy to add support to
the software I am involved in (MRIcron, NPM, MRIcroGL, MRIcro). I
am also happy to supply a few sample datasets once there is a
consensus regarding the datafields.
-c
-c
Feb 28, 2011 05:02 PM | Jochen Weber
RE: NIFTI-2 proposal
Copy that :) changes seem reasonable and straight forward.
I was just
wondering ... is there a particular reason to keep any of the unused fields (see char data_type[10] or db_name[18] from http://nifti.nimh.nih.gov/pub/dist/src/n... for instance)? I would think it's easy enough to set these to default values as part of an output filter that saves a NIFTI-2 struct/image as a NIFTI-1 or Analyze 7.5 header stream to disk; in that case, maybe a total header size (incl. a null-extension) of 512 could be achieved, which might make mapping into a compound object (where actual image data is located in the same file on disk) a little more efficient, given that accessing data slice-by-slice on harddisks still makes it more likely to hit a block boundary for raw images with a 64x64 or 128x128 matrix...
/jochen
I was just
wondering ... is there a particular reason to keep any of the unused fields (see char data_type[10] or db_name[18] from http://nifti.nimh.nih.gov/pub/dist/src/n... for instance)? I would think it's easy enough to set these to default values as part of an output filter that saves a NIFTI-2 struct/image as a NIFTI-1 or Analyze 7.5 header stream to disk; in that case, maybe a total header size (incl. a null-extension) of 512 could be achieved, which might make mapping into a compound object (where actual image data is located in the same file on disk) a little more efficient, given that accessing data slice-by-slice on harddisks still makes it more likely to hit a block boundary for raw images with a 64x64 or 128x128 matrix...
/jochen
Feb 28, 2011 05:02 PM | Denis Rivière
RE: NIFTI-2 proposal
I would just suggest *not* allowing the Analyze file extensions
.img/.hdr since it may introduce confusions, especially for older,
non-nifti-aware software: in any case NIFTI-2 will not be
back-compatible with these software, some of which may crash or
misinterpret image files, so why allow the same file extension ?
Otherwise we also will support the NIFTI-2 format in the BrainVisa world, based on the sourceforge implementation of the nifti C library when it is ready.
Denis
Otherwise we also will support the NIFTI-2 format in the BrainVisa world, based on the sourceforge implementation of the nifti C library when it is ready.
Denis
Feb 28, 2011 05:02 PM | Cinly Ooi
RE: NIFTI-2 proposal
Sounds OK to me.
Is it possible to keep the magic string at the same location? That way we get rid of reading the first four bytes completely. What is the argument behind reading the first four byte just to know how much to jump to?
The reason for raising this is analyze-compatibility, which I thought was the main reason for putting magic string at the end instead of the front, is completely out of the window with NifTI 2. Furthermore, there is a need to reassign value to each byte on the header give the opportunity to rearrange the order of elements. Finally, it would be less complicated to jump a fixed number of bytes (344) to check the magic string instead of having to read the first four byte to decide what to do. Also, it is the norm to keep location of magic string fixed rather than variable as in the proposal.
Best regards,
Cinly
Is it possible to keep the magic string at the same location? That way we get rid of reading the first four bytes completely. What is the argument behind reading the first four byte just to know how much to jump to?
The reason for raising this is analyze-compatibility, which I thought was the main reason for putting magic string at the end instead of the front, is completely out of the window with NifTI 2. Furthermore, there is a need to reassign value to each byte on the header give the opportunity to rearrange the order of elements. Finally, it would be less complicated to jump a fixed number of bytes (344) to check the magic string instead of having to read the first four byte to decide what to do. Also, it is the norm to keep location of magic string fixed rather than variable as in the proposal.
Best regards,
Cinly
Feb 28, 2011 06:02 PM | Satrajit Ghosh
RE: NIFTI-2 proposal
Originally posted by Denis Rivière:
since backwards compatibility is not an issue, let's move as far away as possible from analyze memories :)
I would just suggest *not* allowing the Analyze
file extensions .img/.hdr
+1since backwards compatibility is not an issue, let's move as far away as possible from analyze memories :)
Feb 28, 2011 07:02 PM | Michael Martinez
RE: NIFTI-2 proposal
We will add support for Nifti2 to Mango. Also agree with
other commenters, in favor of dropping support for the old hdr/img
format and only supporting single-file nii.
-Michael
-Michael
Mar 1, 2011 02:03 AM | Randall Frank
RE: NIFTI-2 proposal
Originally posted by Jochen Weber:
The changes seem fine to me as well and I agree with other comments like the above. IMHO, what is imporatant here is that the interpretation of the fields remains true to NIFTI-1 (and your proposal reflects that). This keeps the "business logic" of the apps the same as that in NIFTI-1, which is the biggest win. As long as you are breaking binary compatibility (early arguments for NIFTI), I would encourage more aggressive changes to the header as well. Drop unused fields, standardize the types of the fields, use a page aligned header size (given the size of data files implicit in the proposal, make the header 4k with space for new things) and use a new filename extension. Most of us will read this through another library and as long as the field interpretation does not change, I just need to know offsets and sizes of the fields, along with magic and an endian test to modify my readers. In any case, I like the change.
rjf.
Copy that :) changes seem reasonable and
straight forward.
I was just
wondering ... is there a particular reason to keep any of the unused fields (see char data_type[10] or db_name[18] from http://nifti.nimh.nih.gov/pub/dist/src/n... for instance)? I would think it's easy enough to set these to default values as part of an output filter that saves a NIFTI-2 struct/image as a NIFTI-1 or Analyze 7.5 header stream to disk; in that case, maybe a total header size (incl. a null-extension) of 512 could be achieved, which might make mapping into a compound object (where actual image data is located in the same file on disk) a little more efficient, given that accessing data slice-by-slice on harddisks still makes it more likely to hit a block boundary for raw images with a 64x64 or 128x128 matrix...
/jochen
I was just
wondering ... is there a particular reason to keep any of the unused fields (see char data_type[10] or db_name[18] from http://nifti.nimh.nih.gov/pub/dist/src/n... for instance)? I would think it's easy enough to set these to default values as part of an output filter that saves a NIFTI-2 struct/image as a NIFTI-1 or Analyze 7.5 header stream to disk; in that case, maybe a total header size (incl. a null-extension) of 512 could be achieved, which might make mapping into a compound object (where actual image data is located in the same file on disk) a little more efficient, given that accessing data slice-by-slice on harddisks still makes it more likely to hit a block boundary for raw images with a 64x64 or 128x128 matrix...
/jochen
The changes seem fine to me as well and I agree with other comments like the above. IMHO, what is imporatant here is that the interpretation of the fields remains true to NIFTI-1 (and your proposal reflects that). This keeps the "business logic" of the apps the same as that in NIFTI-1, which is the biggest win. As long as you are breaking binary compatibility (early arguments for NIFTI), I would encourage more aggressive changes to the header as well. Drop unused fields, standardize the types of the fields, use a page aligned header size (given the size of data files implicit in the proposal, make the header 4k with space for new things) and use a new filename extension. Most of us will read this through another library and as long as the field interpretation does not change, I just need to know offsets and sizes of the fields, along with magic and an endian test to modify my readers. In any case, I like the change.
rjf.
Mar 1, 2011 05:03 AM | Andrew Janke
RE: NIFTI-2 proposal
Hi Mark,
I can't see this being a problem, but would echo what others said about killing the .hdr/.img duple support. I'm also one for keeping the changes simple at this point (not changing other parts of the header while you are at it), the reason being is that the NifTi header is always going to be restrictive in what you can put in there. Extra bits should be added as NifTi comments or as you mention done as part of a NifTi successor.
At least if niftilib is going to support this without any hassle to me that's more than a good reason for us here in MINC-land to use it instead of our own home-grown nifti reading/writing libraries. So thumbs up from MINC.
Still I am curious, just how much RAM do you lot have to have exhausted 32767*32767*x?
a
I can't see this being a problem, but would echo what others said about killing the .hdr/.img duple support. I'm also one for keeping the changes simple at this point (not changing other parts of the header while you are at it), the reason being is that the NifTi header is always going to be restrictive in what you can put in there. Extra bits should be added as NifTi comments or as you mention done as part of a NifTi successor.
At least if niftilib is going to support this without any hassle to me that's more than a good reason for us here in MINC-land to use it instead of our own home-grown nifti reading/writing libraries. So thumbs up from MINC.
Still I am curious, just how much RAM do you lot have to have exhausted 32767*32767*x?
a
Mar 1, 2011 11:03 AM | Brandon Whitcher
RE: NIFTI-2 proposal
Originally posted by Denis Rivière:
I also agree with the break from ANALYZE conventions.
There are now several packages in the R programming environment for the analysis of medical imaging data in the NIfTI format. We would be happy to embrace the NIfTI-2 standard.
BW
I would just suggest *not* allowing the Analyze
file extensions .img/.hdr since it may introduce confusions,
especially for older, non-nifti-aware software: in any case NIFTI-2
will not be back-compatible with these software, some of which may
crash or misinterpret image files, so why allow the same file
extension ?
I also agree with the break from ANALYZE conventions.
There are now several packages in the R programming environment for the analysis of medical imaging data in the NIfTI format. We would be happy to embrace the NIfTI-2 standard.
BW
Mar 1, 2011 12:03 PM | Mark Horsfield - Xinapse Systems Ltd
RE: NIFTI-2 proposal
Hi Mark,
I don't see a problem with the 64-bit update, but this modifcation makes a problem I have with the current NIFTI-1 format even more acute.
The current problem I have (I don't know if anyone else does) is the location of the Extensions, just after the header, and before the image data. This means that when an image is created and the image data has been written to disk, it is not possible to add anything to the extensions. The image data is in a fixed location on disk, and the space between the header and the image data is set by the number of bytes in the extension at the time the image data is first written. I believe the current way to add information to the Extensions is to read the whole of the image data from disk (into memory), add to the extensions, and then write the image data back to disk at a new location.
For large datasets (which the modifcation is intended to support) it will not be possible to hold the whole of the image data in memory. The only other way then is to write some clever software to read the image data in chunks, starting at the end of the image data, and shuffling it about on the disk to accommodate the Extension data which has changed size. This isn't very practical if you just want to add a few bytes of Extension data.
This would be solved by moving the Extensions to the end of the image data.
Regards
Mark
I don't see a problem with the 64-bit update, but this modifcation makes a problem I have with the current NIFTI-1 format even more acute.
The current problem I have (I don't know if anyone else does) is the location of the Extensions, just after the header, and before the image data. This means that when an image is created and the image data has been written to disk, it is not possible to add anything to the extensions. The image data is in a fixed location on disk, and the space between the header and the image data is set by the number of bytes in the extension at the time the image data is first written. I believe the current way to add information to the Extensions is to read the whole of the image data from disk (into memory), add to the extensions, and then write the image data back to disk at a new location.
For large datasets (which the modifcation is intended to support) it will not be possible to hold the whole of the image data in memory. The only other way then is to write some clever software to read the image data in chunks, starting at the end of the image data, and shuffling it about on the disk to accommodate the Extension data which has changed size. This isn't very practical if you just want to add a few bytes of Extension data.
This would be solved by moving the Extensions to the end of the image data.
Regards
Mark
Mar 1, 2011 01:03 PM | Jonas Larsson
RE: NIFTI-2 proposal
This is a good idea but I'd like to chime in with everyone else
that this would be an auspicious opportunity to once and for all
leave the Analyze legacy behind and settle on a modern file format.
The best solution would be to retain only those fields that are
absolutely necessary, recode the qform in full 4x4 matrix format
rather than going through the inconvenience of quaternions (which
was only ever motivated by the need to remain within the 348 byte
limit) and in general make the header much more well structured.
The easiest way would be to implement all this as XML in a text
header as was permitted in the original Nifti-1 specification in
.nii files, and entirely scrap the binary part of the header.
There are many freely available tools for parsing XML so it should not be too difficult to implement this change - merely retaining the old format header with a few 64-bit fields is a temporary solution that will eventually have to be replaced by a Nifti-3 version and seems like an unnecessary effort in the longer term.
There are many freely available tools for parsing XML so it should not be too difficult to implement this change - merely retaining the old format header with a few 64-bit fields is a temporary solution that will eventually have to be replaced by a Nifti-3 version and seems like an unnecessary effort in the longer term.
Mar 1, 2011 02:03 PM | Cinly Ooi
RE: NIFTI-2 proposal
Originally posted by Denis Rivière:
I don't think having two separate files for a dataset is the problem, but the extension can cause problem. IMHO we simply have to rename them to .nim/.ndr or something else that separate them from Analyze.
Having separate hdr/img file has its advantages, e.g. one can just import the img file as raw data into third parties software, e.g. (non-neuroimaging image viewer) and set the dim[] and datatype information separately or pull data out of the third party software than clone the hdr from somewhere else.
I would just suggest *not* allowing the Analyze
file extensions .img/.hdr since it may introduce confusions,
especially for older, non-nifti-aware software: in any case NIFTI-2
will not be back-compatible with these software, some of which may
crash or misinterpret image files, so why allow the same file
extension ?
Otherwise we also will support the NIFTI-2 format in the BrainVisa world, based on the sourceforge implementation of the nifti C library when it is ready.
Denis
Otherwise we also will support the NIFTI-2 format in the BrainVisa world, based on the sourceforge implementation of the nifti C library when it is ready.
Denis
I don't think having two separate files for a dataset is the problem, but the extension can cause problem. IMHO we simply have to rename them to .nim/.ndr or something else that separate them from Analyze.
Having separate hdr/img file has its advantages, e.g. one can just import the img file as raw data into third parties software, e.g. (non-neuroimaging image viewer) and set the dim[] and datatype information separately or pull data out of the third party software than clone the hdr from somewhere else.
Mar 1, 2011 02:03 PM | Cinly Ooi
Proposal : set the image orientation
Dear All,
Image orientation (Radiological/Neurological) is still a big problem. NifTI-1, IMHO (which may be wrong) actually adds to the confusion rather than saving us from it coz I have to worry about two things: (1) Whether software X flips the image and (2)whether software honour sform_code or pform_code. Is there any possibility that the image orientation is fixed to either radiological/neurological.
The reason is this means all software will be free of this problem once and for all. I don't have to check whether an image is flipped by XXX software, mricro need not tell me that it does not flip images etc. Moreover, this means we deal with the image orientation at one place, i.e. interface between scanner's DICOM server and nifTI conversion. This is the place where most imaging expertise in handling imaging data is.
Thanks
Cinly
Image orientation (Radiological/Neurological) is still a big problem. NifTI-1, IMHO (which may be wrong) actually adds to the confusion rather than saving us from it coz I have to worry about two things: (1) Whether software X flips the image and (2)whether software honour sform_code or pform_code. Is there any possibility that the image orientation is fixed to either radiological/neurological.
The reason is this means all software will be free of this problem once and for all. I don't have to check whether an image is flipped by XXX software, mricro need not tell me that it does not flip images etc. Moreover, this means we deal with the image orientation at one place, i.e. interface between scanner's DICOM server and nifTI conversion. This is the place where most imaging expertise in handling imaging data is.
Thanks
Cinly
Mar 1, 2011 02:03 PM | Cinly Ooi
Proposal : Not using pixdim[0] as qfac
Dear All,
Since we arre discussing possible reorganization, can I recommend not using pixdim[0] as qfac. It causes confusion at every step and I think we can spare 8 bytes for qfac to have its own special field.
Why it causes confusion? Normal people does not expect pixdim[0] to be used this way. I have to tell new programmers to watch out for it. If I use nifti_tool -mod_hdr to fix pixdim I have to be aware not to upset pixdim[0]. When using nifticlib I have to take care not to change nim->pixdim[0].
Can I propose that it is used to indicate how many pixdim element is valid, i.e. pixdim[0]=4 means pixdim[1..4] is valid. This give us the ability to say the pixels does not have any physical dimension by setting pixdim[0] to 0.
Thanks
Cinly
Since we arre discussing possible reorganization, can I recommend not using pixdim[0] as qfac. It causes confusion at every step and I think we can spare 8 bytes for qfac to have its own special field.
Why it causes confusion? Normal people does not expect pixdim[0] to be used this way. I have to tell new programmers to watch out for it. If I use nifti_tool -mod_hdr to fix pixdim I have to be aware not to upset pixdim[0]. When using nifticlib I have to take care not to change nim->pixdim[0].
Can I propose that it is used to indicate how many pixdim element is valid, i.e. pixdim[0]=4 means pixdim[1..4] is valid. This give us the ability to say the pixels does not have any physical dimension by setting pixdim[0] to 0.
Thanks
Cinly
Mar 1, 2011 03:03 PM | Cinly Ooi
Proposal: nifticlib - remove nx,ny,..dx,...
Dear All,
I am not sure how much reworking of nifticlib is planned. I hope not much. But if you are thinking about big rework can I suggest not having duplicate-looking variables storing the same information?
My problem here is nx,ny,nz... and dx, dy, dz ... is effectively a duplication of dim[1..] and pixdim[1.]. As programmers we are more used to using dim[] and pixdim[] instead of nX and dX. Having both nX/dX and dim[]/pixdim[] causes confusion, as C cannot easily keep them in sync. Eliminating nX and dX will remove this confusion. It took me quite a lot of debugging to work out that nX has priority overe dim[] in nifticlib and that setting dim[] in nifti_image has no effect when writing image file using nifti_image_write because it will be overwritten by nX and I am not alone in this.
However, I recognize that nifticlib itself, and a lot of other programs might actually uses nX and dX and therefore, it is not an easy decision to make to retires nX/dX.
Thanks
Cinly
I am not sure how much reworking of nifticlib is planned. I hope not much. But if you are thinking about big rework can I suggest not having duplicate-looking variables storing the same information?
My problem here is nx,ny,nz... and dx, dy, dz ... is effectively a duplication of dim[1..] and pixdim[1.]. As programmers we are more used to using dim[] and pixdim[] instead of nX and dX. Having both nX/dX and dim[]/pixdim[] causes confusion, as C cannot easily keep them in sync. Eliminating nX and dX will remove this confusion. It took me quite a lot of debugging to work out that nX has priority overe dim[] in nifticlib and that setting dim[] in nifti_image has no effect when writing image file using nifti_image_write because it will be overwritten by nX and I am not alone in this.
However, I recognize that nifticlib itself, and a lot of other programs might actually uses nX and dX and therefore, it is not an easy decision to make to retires nX/dX.
Thanks
Cinly
Mar 1, 2011 03:03 PM | Cinly Ooi
Proposal : Cleaning up nifticlib file i/o
Dear All,
If nifticlib is to be reworked, can I propose contemplating the clean up file i/o section of nifticlib?
The current solution works, so I am not sure whether it is a good idea to clean up file i/o. But since the worst I will get is someone flaming me and that is unlikely on this forum, I will say my piece and leave it at it.
The issue is the physical file read/write part of nifticlib has to deal with four different formats (hdr/img, nii and their gzip counterpart). The current system effectively requires the niftilib read write function to deal with it themselves. This results in quite a lot of code looking like this:
if (filetype==hdr) then writeHdrImg()
else if (filetype==hdr.gz) then writeHdrImgGz()
else if (filetype==nii) then writeNii()
else if (filetype==nii.gz) then writeNiiGZ()
As each function has to implement this, it becomes a nightmare to introduce new read/write as all functions doing read/write has to be updated. If nifticlib maintainer wants to introduce the ability to read and write nifti1 and nifti2 simultaneously in this update, another 4 formats (for nifti 2) has to be supported.
I think a better solution worth considering is to use function pointers. This way, say we simply need one read and one write function. We modify nifti_image struct to carry function pointers for the two, e.g.
struct nifti_image {
...
*(fn_read)(...)
*(fn_write)(...)
}
and each of the file format supported will define its own fn_read and fn_write function, e.g.
* hdr : fn_hdr_read(...)/fn_hdr_write(...)
* hdr.gz: fn_hdrgz_read(...)/fn_hdrgz_write(...)
* nii : fn_nii_read(...)/fn_nii_write(...)
* nii.gz: fn_niigz_read(...)/fn_niigz_write(...)
Then, a function will be responsible for attaching the correct set of function pointers to nifti_image, say
function setIOPointers(nim) {
if (hdr) { nim->fn_read = fn_hdr_read; nim->fn_write=fn_hdr_write; }
...
}
This way, any function that needs to read/write simply has to call
nim->fn_read()
or
nim->fn_write()
instead of the if-else statement in the first example
The advantage is we centralize all read/write function maintenance at one place and make it easier to introduce new format or take old format out.
Thanks and HTH
Cinly
If nifticlib is to be reworked, can I propose contemplating the clean up file i/o section of nifticlib?
The current solution works, so I am not sure whether it is a good idea to clean up file i/o. But since the worst I will get is someone flaming me and that is unlikely on this forum, I will say my piece and leave it at it.
The issue is the physical file read/write part of nifticlib has to deal with four different formats (hdr/img, nii and their gzip counterpart). The current system effectively requires the niftilib read write function to deal with it themselves. This results in quite a lot of code looking like this:
if (filetype==hdr) then writeHdrImg()
else if (filetype==hdr.gz) then writeHdrImgGz()
else if (filetype==nii) then writeNii()
else if (filetype==nii.gz) then writeNiiGZ()
As each function has to implement this, it becomes a nightmare to introduce new read/write as all functions doing read/write has to be updated. If nifticlib maintainer wants to introduce the ability to read and write nifti1 and nifti2 simultaneously in this update, another 4 formats (for nifti 2) has to be supported.
I think a better solution worth considering is to use function pointers. This way, say we simply need one read and one write function. We modify nifti_image struct to carry function pointers for the two, e.g.
struct nifti_image {
...
*(fn_read)(...)
*(fn_write)(...)
}
and each of the file format supported will define its own fn_read and fn_write function, e.g.
* hdr : fn_hdr_read(...)/fn_hdr_write(...)
* hdr.gz: fn_hdrgz_read(...)/fn_hdrgz_write(...)
* nii : fn_nii_read(...)/fn_nii_write(...)
* nii.gz: fn_niigz_read(...)/fn_niigz_write(...)
Then, a function will be responsible for attaching the correct set of function pointers to nifti_image, say
function setIOPointers(nim) {
if (hdr) { nim->fn_read = fn_hdr_read; nim->fn_write=fn_hdr_write; }
...
}
This way, any function that needs to read/write simply has to call
nim->fn_read()
or
nim->fn_write()
instead of the if-else statement in the first example
The advantage is we centralize all read/write function maintenance at one place and make it easier to introduce new format or take old format out.
Thanks and HTH
Cinly
Mar 1, 2011 05:03 PM | Cinly Ooi
Proposal : Permitting Custom Field Value
Dear All,
While NifTI tries its very best to be inclusive, there will always be time where the NifTI format did not account for certain use case, or advancement in the field required data to be stored in a way that NifTI did not anticipate.
In these cases, it is inevitable that developers will simply create a customised version of NifTI for their own use. NifTI's licensing T&C permits them to do this, giving us no recourse (even legal one) if someone insisting on customising NifTI. That is assuming we want to prohibit creation of customisation of NifTI in the first place which we don't.
We can, however, guide these customisation so that there will be less conflict with existing NifTI format. Some of these effort are simply minor changes that has very minor impact in everyday use of NifTI.
In NifTI, if we permit customisation in datatype (NIFTI_TYPE_*), intent code (NIFTI_INTENT_*), xform code (NIFTI_XFORM_), measurement unit (NIFTI_UNITS_) and slice sequence (NIFTI_SLICE_*), then together with nifti_extension, virtually anything we envisage to use in neuroimaging will be covered.
To provide guidance to customisation, what we have to do is to define a range, e.g. say 2020-2047 for NIFTI_INTENT_* (highest defined is 2005 for NIFTI_INTENT_SHAPE), which users can use to define anything they want. The NifTI standard will not use code in this range when defining new constants in return for them using codes in the defined range. This way, instead of user using any code to define their customisation, we restrict them to known codes.
In C, it is common to mark the range using a preprocessor constant, e.g
#define NIFTI_INTENT_CUSTOM 2020 /* USER CUSTOM INTENT CODE 2020-2047 inclusive */
This system is like DICOM's even number group code, which DICOM reserves for use by anyone who care to put custom data into dicom.
Thanks
Cinly
While NifTI tries its very best to be inclusive, there will always be time where the NifTI format did not account for certain use case, or advancement in the field required data to be stored in a way that NifTI did not anticipate.
In these cases, it is inevitable that developers will simply create a customised version of NifTI for their own use. NifTI's licensing T&C permits them to do this, giving us no recourse (even legal one) if someone insisting on customising NifTI. That is assuming we want to prohibit creation of customisation of NifTI in the first place which we don't.
We can, however, guide these customisation so that there will be less conflict with existing NifTI format. Some of these effort are simply minor changes that has very minor impact in everyday use of NifTI.
In NifTI, if we permit customisation in datatype (NIFTI_TYPE_*), intent code (NIFTI_INTENT_*), xform code (NIFTI_XFORM_), measurement unit (NIFTI_UNITS_) and slice sequence (NIFTI_SLICE_*), then together with nifti_extension, virtually anything we envisage to use in neuroimaging will be covered.
To provide guidance to customisation, what we have to do is to define a range, e.g. say 2020-2047 for NIFTI_INTENT_* (highest defined is 2005 for NIFTI_INTENT_SHAPE), which users can use to define anything they want. The NifTI standard will not use code in this range when defining new constants in return for them using codes in the defined range. This way, instead of user using any code to define their customisation, we restrict them to known codes.
In C, it is common to mark the range using a preprocessor constant, e.g
#define NIFTI_INTENT_CUSTOM 2020 /* USER CUSTOM INTENT CODE 2020-2047 inclusive */
This system is like DICOM's even number group code, which DICOM reserves for use by anyone who care to put custom data into dicom.
Thanks
Cinly
Mar 1, 2011 11:03 PM | Andrew Janke
RE: Proposal : set the image orientation
+10 on removing the radio/neuro schemozzle.
But I'd prefer that NifTi just stores the data in a well defined co-ordinate system, like DICOM/MINC/etc. eg in MINC we have this:
X increases from patient left to right
Y increases from patient posterior to anterior
Z increases from patient inferior to superior
This is all we need as the whole neuro vs radio debate should not be about storage, its a viewing convention and should be left at that. My thought is all you need is a checkbox/preference setting for fslview/SPM/freesurfer that allows you to view your data in your particular flavour. We currently don't have such a checkbox in register/Display/other minc viewing things but then there has never been a call for it that I have heard. All MINC viewing tools are neuro oriented.
A side note is that there are ruminations afoot right now to read/write NifTi files with MINC, I for one am opposing it right now as I am loathe to drag MINC into this radio vs neuro "format" mess. As Cinly mentions, currently if I am given a NifTi file to import I cannot resolve the L/R issue unless I know something about the files provenance.
a
But I'd prefer that NifTi just stores the data in a well defined co-ordinate system, like DICOM/MINC/etc. eg in MINC we have this:
X increases from patient left to right
Y increases from patient posterior to anterior
Z increases from patient inferior to superior
This is all we need as the whole neuro vs radio debate should not be about storage, its a viewing convention and should be left at that. My thought is all you need is a checkbox/preference setting for fslview/SPM/freesurfer that allows you to view your data in your particular flavour. We currently don't have such a checkbox in register/Display/other minc viewing things but then there has never been a call for it that I have heard. All MINC viewing tools are neuro oriented.
A side note is that there are ruminations afoot right now to read/write NifTi files with MINC, I for one am opposing it right now as I am loathe to drag MINC into this radio vs neuro "format" mess. As Cinly mentions, currently if I am given a NifTi file to import I cannot resolve the L/R issue unless I know something about the files provenance.
a
Mar 2, 2011 01:03 PM | Cinly Ooi
RE: Proposal : set the image orientation
Dear Andrew,
Thanks for the support. +10 was unexpected. Was only expecting +1
Sorry for framing it as a storage problem. I tend to look things from the storage viewpoint.
The reason for framing it as a storage problem is I thought by fixing the orientation as storage we can solve these problems:
The reason for transforming orientation to storage problem is the scanner is usually the place with the most programming expertise or best information source (physicist, radiographers) so it is the best place to handle the orientation problem. Furthermore, we nip the problem in the bud if we resolve it there.
HTH
Cinly
Thanks for the support. +10 was unexpected. Was only expecting +1
Sorry for framing it as a storage problem. I tend to look things from the storage viewpoint.
The reason for framing it as a storage problem is I thought by fixing the orientation as storage we can solve these problems:
- The viewing problem as you had so well described: The theory goes that if I set the storage orientation, then you can be sure that your viewing convention is always correct without (1) referring to a particular checkbox and (2)[more importantly] worrying whether a nifti file created by third party actually remember to set the the bit or not. Believe it or not, it is difficult for a programmer to remember whether he set a checkbox to true/false. [I share your sentiment/problems with viewing. It is perhaps worse for me as I don't write my own viewing program and has to rely on third parties. In fact, my favourite image viewing program is to write out the images as it is (ignores any orientation information) in PNG and view it using preview]
- Most users simply do not even know about the different in orientation, they just accept whatever the program tells them as the gospel truth. That's not good.
- Worse still when we get data from multiple centres with different convention and nobody from the centre can tell us definitely what their orientation is. It is a big go around, asking radiographers, physicist or just about everyone we can think of, then experiment with the data to confirm orientation. Even then, sometimes we have to fudge it. In fact, sometimes I am hoping something like left brain activated by left hand movement (for right hander) happens in every dataset we have to confirm that we got the orientation wrong so that we can correct it.
- There are programs that (1)simply ignores orientation, (2)some program reads orientation, the flip the images and (3)some programs read and honour orientation, but can sometimes fail to set the orientation bit corrrectly when creating the output. Having two ways of storing orientation (sform and qform) is not helping either. [Please note that I am just arguing orientation information shouldn't be store in them, not that they are not useful. Although I would say it should had been only either sform or qform, and use the 3x4 transformation matrix notation only]
- Mixing programs from different analysis suit is almost impossible because of the orientation mix up, or we simply don't know how the orientation is handled.
- The most coherent approach I seen in dealing with orientation is FSL, where it put out a statement on how its programs treat orientation information. That is still simpy another way of saying orientation is the users' problem. In some sense that is simply confirming that you the user is responsible for orientation issue. Given the current situation, IMHO FSL's hand is forced.
- My approach? Unless I tell you I read orientation information, I don't. I simply copy your input hdr to the output hdr as well.
The reason for transforming orientation to storage problem is the scanner is usually the place with the most programming expertise or best information source (physicist, radiographers) so it is the best place to handle the orientation problem. Furthermore, we nip the problem in the bud if we resolve it there.
HTH
Cinly
Mar 2, 2011 01:03 PM | Cinly Ooi
Proposal: merge xform_code and use 3x4 matrix
Dear All,
I understand the reason behind pform_code and sform_code. However, I think its implementation can be improved.
I think use of two different forms, and the fact that both can coesxist complicate works seriously for me. Alllowing user to specify only one save me a lot of trouble. I still yet to see a program that needs both, but have to admit I proabably did not see the full picture of NifTI usage.
And while I can see the restriction on sform_code compared to pform_code, I cannot exactly why sform_code cannot be store as 3x4 matrix. That makes reading the transformation matrix easier for us joe user.
Frankly, it is easy to reverse engineer 3x4 transformation matrix to sform format. nifticlib even conveniently gives you a function to do that. IMHO any worry about the sform cofficients not being exact after the transformation is misplaced. If your coefficients are sensitive to 8 s.f. then probably you should start asking question about your algorithm. Furthermore, in NifTI 2 we are using double datatype, not float to represent the data. Therefore, the problem with imprecise coef is reduced.
Perhaps this should be seen as a plea from users like me who have to constantly worry about whether I should transform from sform code to pform code, whether if both are present, they are referring to the same thing and if they don't, what am I to do?
Thanks
Cinly
I understand the reason behind pform_code and sform_code. However, I think its implementation can be improved.
I think use of two different forms, and the fact that both can coesxist complicate works seriously for me. Alllowing user to specify only one save me a lot of trouble. I still yet to see a program that needs both, but have to admit I proabably did not see the full picture of NifTI usage.
And while I can see the restriction on sform_code compared to pform_code, I cannot exactly why sform_code cannot be store as 3x4 matrix. That makes reading the transformation matrix easier for us joe user.
Frankly, it is easy to reverse engineer 3x4 transformation matrix to sform format. nifticlib even conveniently gives you a function to do that. IMHO any worry about the sform cofficients not being exact after the transformation is misplaced. If your coefficients are sensitive to 8 s.f. then probably you should start asking question about your algorithm. Furthermore, in NifTI 2 we are using double datatype, not float to represent the data. Therefore, the problem with imprecise coef is reduced.
Perhaps this should be seen as a plea from users like me who have to constantly worry about whether I should transform from sform code to pform code, whether if both are present, they are referring to the same thing and if they don't, what am I to do?
Thanks
Cinly
Mar 5, 2011 01:03 PM | Jon Clayden - University College London
RE: NIFTI-2 proposal
I agree with Andrew that data ordering/slicing (LAS/RAS etc.)
should be a visualisation question and not a storage one. It would
certainly simplify things, and no doubt save many people some
grief, if there were one standard storage convention.
I am happy with the proposal, and willing to add support for NIfTI-2 in TractoR; but if Analyze backwards compatibility is to be broken, it does seem like an opportunity to consider some wider changes to the format.
All the best,
Jon
I am happy with the proposal, and willing to add support for NIfTI-2 in TractoR; but if Analyze backwards compatibility is to be broken, it does seem like an opportunity to consider some wider changes to the format.
All the best,
Jon
Mar 5, 2011 02:03 PM | Satrajit Ghosh
RE: Proposal : set the image orientation
indeed orientation is a big practical problem but so are numerous
interpolations that come with resampling the data. if one wanted to
maintain storage in a specific order, wouldn't the data would have
to be resampled?
having a transformation matrix (or multiple matrices - that nifti currently doesn't allow), allows us to redefine orientation that best suits an application without resampling the data.
having a transformation matrix (or multiple matrices - that nifti currently doesn't allow), allows us to redefine orientation that best suits an application without resampling the data.
Mar 7, 2011 11:03 AM | Ged Ridgway
RE: Proposal: merge xform_code and use 3x4 matrix
Originally posted by Cinly Ooi:
Hi,
Probably not strictly a "need", but SPM does currently use both in one situation: when images are rigidly aligned to MNI ("imported") for use with DARTEL (or the new Geodesic Shooting) registration tool, the two transforms are used so that the nonrigid transformation can be derived from the resliced images but applied to the originals (i.e. the rigid then DARTEL transformations don't involve interpolating twice). Obviously there are other ways of doing this, but I guess John did this to avoid having to save the rigid transformation anywhere other than the NIfTI image itself.
Perhaps a very simple standard format (or even simpler documentation of how to do it with the current format) specifically for saving transformations would be helpful? This is something which is not currently standardised across packages (e.g. one can't easily take flirt and/or fnirt transformations from FSL and transform an image in SPM, or use them to initialise a voxel-wise deformation), but it seems that it could and should be if they are using the same image file format.
For voxel-wise non-rigid transformations, SPM is already saving vector fields with components along the 5th dimension, as specified in the NIfTI standard, though I think the standard is a little ambiguous about whether a transformation vector field contains offsets (identity transform being all zeros) or coordinates of where voxels map to (i.e. original location plus offset), and whether these are in voxels or millimetres. A little documentation would probably suffice to standardise that.
For B-spline transformations, one could use the sform to specify the control point locations, and then use a vector field as before; again the main problem would be to document the standard and persuade different software packages to agree on it. For the simpler affine and rigid cases, presumably we could simply use NIfTI "images" without any imaging data, with all dimensions zero, and the transform just in the sform (no obvious advantage to allowing qform too?).
NIfTI2 seems like a good opportunity to try to standardise some of these usages which are already possible, without any changes to the library, just some agreement across different developers and groups. What do people think?
All the best,
Ged
P.S. Related point, while I think of it... Motion correction of 4D time-series changes the voxel-world mapping for each volume; if one doesn't want to reslice the data at this stage (e.g. because motion corrected data will be registered to a structural image and/or normalised to MNI) then this breaks the NIfTI format slightly, since the 4D series can have only one sform (and one qform, but that doesn't help here). SPM's solution to this is to save a matlab variable with the list of transformation matrices, but it would be much nicer either to allow nifti2 to have one transform per 3D volume, or to standardise the storage of transformations in NIfTI format, so that SPM could use this instead of matlab's format, and potentially allow consistency across multiple packages that do motion correction and/or subsequent processing.
I think use of two different forms, and the fact
that both can coesxist complicate works seriously for me. Alllowing
user to specify only one save me a lot of trouble. I still yet to
see a program that needs both, but have to admit I proabably did
not see the full picture of NifTI usage.
Hi,
Probably not strictly a "need", but SPM does currently use both in one situation: when images are rigidly aligned to MNI ("imported") for use with DARTEL (or the new Geodesic Shooting) registration tool, the two transforms are used so that the nonrigid transformation can be derived from the resliced images but applied to the originals (i.e. the rigid then DARTEL transformations don't involve interpolating twice). Obviously there are other ways of doing this, but I guess John did this to avoid having to save the rigid transformation anywhere other than the NIfTI image itself.
Perhaps a very simple standard format (or even simpler documentation of how to do it with the current format) specifically for saving transformations would be helpful? This is something which is not currently standardised across packages (e.g. one can't easily take flirt and/or fnirt transformations from FSL and transform an image in SPM, or use them to initialise a voxel-wise deformation), but it seems that it could and should be if they are using the same image file format.
For voxel-wise non-rigid transformations, SPM is already saving vector fields with components along the 5th dimension, as specified in the NIfTI standard, though I think the standard is a little ambiguous about whether a transformation vector field contains offsets (identity transform being all zeros) or coordinates of where voxels map to (i.e. original location plus offset), and whether these are in voxels or millimetres. A little documentation would probably suffice to standardise that.
For B-spline transformations, one could use the sform to specify the control point locations, and then use a vector field as before; again the main problem would be to document the standard and persuade different software packages to agree on it. For the simpler affine and rigid cases, presumably we could simply use NIfTI "images" without any imaging data, with all dimensions zero, and the transform just in the sform (no obvious advantage to allowing qform too?).
NIfTI2 seems like a good opportunity to try to standardise some of these usages which are already possible, without any changes to the library, just some agreement across different developers and groups. What do people think?
All the best,
Ged
P.S. Related point, while I think of it... Motion correction of 4D time-series changes the voxel-world mapping for each volume; if one doesn't want to reslice the data at this stage (e.g. because motion corrected data will be registered to a structural image and/or normalised to MNI) then this breaks the NIfTI format slightly, since the 4D series can have only one sform (and one qform, but that doesn't help here). SPM's solution to this is to save a matlab variable with the list of transformation matrices, but it would be much nicer either to allow nifti2 to have one transform per 3D volume, or to standardise the storage of transformations in NIfTI format, so that SPM could use this instead of matlab's format, and potentially allow consistency across multiple packages that do motion correction and/or subsequent processing.
Mar 15, 2011 05:03 PM | Mark Jenkinson
RE: NIFTI-2 proposal
Response to the
postings on the public forum:
The NIfTI
committee thank all those who responded to the public announcement
of the NIfTI-2 proposal. The outcomes of discussions of these
postings and other responses outside of the forum are summarised
below. Please see the associated posting for full details of
the revised, finalised NIfTI-2 format.
Changes
to the proposed NIfTI-2 format:
-
Removal of unused fields (data_type, db_name, extents,
session_error, regular, glmax, glmin).
-
Changing the order of several fields to ensure 8-byte alignment of
all doubles (an issue raised outside of the forum, which would be a
major problem on some platforms if it was not ensured).
-
Shifting the magic string to the front of the header, immediately
following sizeof_hdr.
- A
change in the total header size (including 4-byte extension info)
to become 544 bytes.
- A
range for customised codes for INTENT, XFORM, UNITS and SLICE will
be specified for temporary customisation, although users will
continue to be encouraged to register for official codes and have
them publicly documented to avoid any hidden or private information
polluting the open standard.
Additional points:
-
There was considerable discussion about the hdr/img format and
although several people were in favour of dropping this to distance
the format from the older Analyze standard, it was still being
actively used by some developers and has the potential for
considerable benefit when dealing with very large datasets, where
the header information can be read and modified without requiring
any reading or writing of the data values. Consequently, it was
felt that it was more advantageous to retain the existing hdr/img
format and also leave the extension name for the single format
(.nii) unchanged.
- The
changes in nifticlib will be considered carefully, although these
are separate issues from the definition of the NIfTI-2 standard
itself.
- The
standardisation of spatial transformation information is an
important issue and currently being looked into in a separate
endeavour on developing a standard format for spatial
transformation data.
-
There were several requests for changes in how the spatial
coordinate information is stored and represented (qform and sform)
or even suggestions that the coordinate handedness should be
forced/fixed, and multiple transformations be
incorporated. The original intention of the proposed NIfTI-2
format was to create an easy to implement upgrade of the existing
NIfTI-1 standard that maintains the same information and the same
logic. This was a very important point in getting many of the
developers to agree to implement this NIfTI-2
standard. Several developers depend on the way that the qform
and sform information is currently implemented in NIfTI-1 and
changes in meaning or even storage method could cause problems and
delays in implementing the NIfTI-2 standard. The qform and
sform issues are therefore much bigger issues than being considered
for NIfTI-2 and would alter the logic involved in any
implementation compared to NIfTI-1. Therefore, although these
issues are extremely important, we feel they are more appropriate
for the upcoming discussions on future formats where such major
changes to the logic and implementation can be made without
restriction. All comments should therefore be forwarded to the
discussion forum for future formats.
- A
request to have a pure XML header is also a major change and shares
some of the same issues as the above request, and so should be
forwarded to the discussion forum for future formats. Note
that there has never been an official nifti-1 format that allowed a
purely XML header - there is some code in nifticlib to allow such
XML to be generated, but this was never part of the official
nifti-1 specification.