18
18
19
19
'''
20
20
from __future__ import division , print_function , absolute_import
21
- from ..externals .six import string_types
22
21
23
22
import numpy as np
24
23
25
- DEBUG_PRINT = False
24
+ from ..externals .six import string_types
25
+ from ..filebasedimages import FileBasedImage , FileBasedHeader
26
+ from ..nifti1 import Nifti1Extension
27
+ from ..nifti2 import Nifti2Image
28
+
26
29
27
30
CIFTI_MAP_TYPES = ('CIFTI_INDEX_TYPE_BRAIN_MODELS' ,
28
31
'CIFTI_INDEX_TYPE_PARCELS' ,
@@ -726,7 +729,7 @@ def to_xml(self, prefix='', indent=' '):
726
729
return res
727
730
728
731
729
- class CiftiHeader (object ):
732
+ class CiftiHeader (FileBasedHeader ):
730
733
''' Class for Cifti2 header extension '''
731
734
732
735
version = str
@@ -752,65 +755,88 @@ def from_header(klass, header=None):
752
755
return header .copy ()
753
756
raise ValueError ('header is not a CiftiHeader' )
754
757
755
- class CiftiImage (object ):
758
+ @classmethod
759
+ def may_contain_header (klass , binaryblock ):
760
+ from .parse_cifti_fast import _CiftiAsNiftiHeader
761
+ return _CiftiAsNiftiHeader .may_contain_header (binaryblock )
762
+
763
+
764
+ class CiftiImage (FileBasedImage ):
765
+ # It is a Nifti2Image, but because Nifti2Image object
766
+ # contains both the *format* and the assumption that it's
767
+ # a spatial image, we can't inherit directly.
756
768
header_class = CiftiHeader
769
+ valid_exts = Nifti2Image .valid_exts
770
+ files_types = Nifti2Image .files_types
771
+ makeable = False
772
+ rw = True
757
773
758
774
def __init__ (self , data = None , header = None , nifti_header = None ):
759
- self .header = CiftiHeader ()
760
- if header is not None :
761
- self .header = header
775
+ self ._header = header or CiftiHeader ()
762
776
self .data = data
763
777
self .extra = nifti_header
764
778
765
- @classmethod
766
- def instance_to_filename (klass , img , filename ):
767
- ''' Save `img` in our own format, to name implied by `filename`
779
+ def get_data (self ):
780
+ return self .data
768
781
769
- This is a class method
782
+ @classmethod
783
+ def from_file_map (klass , file_map ):
784
+ """ Load a Gifti image from a file_map
770
785
771
786
Parameters
772
- ----------
773
- img : ``spatialimage`` instance
774
- In fact, an object with the API of ``spatialimage`` -
775
- specifically ``get_data``, ``get_affine``, ``get_header`` and
776
- ``extra``.
777
- filename : str
778
- Filename, implying name to which to save image.
779
- '''
780
- img = klass .from_image (img )
781
- img .to_filename (filename )
787
+ file_map : string
782
788
783
- @classmethod
784
- def from_image (klass , img ):
785
- ''' Class method to create new instance of own class from `img`
789
+ Returns
790
+ -------
791
+ img : GiftiImage
792
+ Returns a GiftiImage
793
+ """
794
+ from .parse_cifti_fast import _CiftiAsNiftiImage , CiftiExtension
795
+ nifti_img = _CiftiAsNiftiImage .from_file_map (file_map )
796
+
797
+ # Get cifti header
798
+ cifti_header = reduce (lambda accum , item : item .get_content ()
799
+ if isinstance (item , CiftiExtension )
800
+ else accum ,
801
+ nifti_img .get_header ().extensions or [],
802
+ None )
803
+ if cifti_header is None :
804
+ raise ValueError (('Nifti2 header does not contain a CIFTI '
805
+ 'extension' ))
806
+
807
+ # Construct cifti image
808
+ cifti_img = CiftiImage (data = np .squeeze (nifti_img .get_data ()),
809
+ header = cifti_header ,
810
+ nifti_header = nifti_img .get_header ())
811
+ cifti_img .file_map = nifti_img .file_map
812
+ return cifti_img
813
+
814
+ def to_file_map (self , file_map = None ):
815
+ """ Save the current image to the specified file_map
786
816
787
817
Parameters
788
818
----------
789
- img : ``spatialimage`` instance
790
- In fact, an object with the API of ``spatialimage`` -
791
- specifically ``get_data``, ``get_affine``, ``get_header`` and
792
- ``extra``.
819
+ file_map : string
793
820
794
821
Returns
795
822
-------
796
- cimg : ``spatialimage`` instance
797
- Image, of our own class
798
- '''
799
- return klass (img ._dataobj ,
800
- klass .header_class .from_header (img .header ),
801
- extra = img .extra .copy ())
802
-
803
- def to_filename (self , filename ):
804
- if not filename .endswith ('nii' ):
805
- ValueError ('CIFTI files have to be stored as uncompressed NIFTI2' )
806
- from ..nifti2 import Nifti2Image
807
- from ..nifti1 import Nifti1Extension
808
- data = np .reshape (self .data , [1 , 1 , 1 , 1 ] + list (self .data .shape ))
823
+ None
824
+ """
825
+ from .parse_cifti_fast import CiftiExtension
809
826
header = self .extra
810
- extension = Nifti1Extension ( 32 , self .header .to_xml ().encode ())
827
+ extension = CiftiExtension ( content = self .header .to_xml ().encode ())
811
828
header .extensions .append (extension )
829
+ data = np .reshape (self .data , [1 , 1 , 1 , 1 ] + list (self .data .shape ))
812
830
img = Nifti2Image (data , None , header )
813
- img .to_filename (filename )
831
+ img .to_file_map (file_map or self .file_map )
832
+
833
+
834
+ class CiftiDenseDataSeriesHeader (CiftiHeader ):
835
+
836
+ @classmethod
837
+ def may_contain_header (klass , binaryblock ):
838
+ from .parse_cifti_fast import _CiftiDenseDataSeriesNiftiHeader
839
+ return _CiftiDenseDataSeriesNiftiHeader .may_contain_header (binaryblock )
814
840
815
841
816
842
class CiftiDenseDataSeries (CiftiImage ):
@@ -831,7 +857,9 @@ class CiftiDenseDataSeries(CiftiImage):
831
857
series of sampling depths along the surface normal from the white to pial
832
858
surface. It retains the 't' in dtseries from CIFTI-1 naming conventions.
833
859
"""
834
- suffix = '.dtseries.nii'
860
+ header_class = CiftiDenseDataSeriesHeader
861
+ valid_exts = ('.dtseries.nii' ,)
862
+ files_types = (('image' , '.dtseries.nii' ),)
835
863
836
864
837
865
def load (filename ):
@@ -852,8 +880,8 @@ def load(filename):
852
880
ImageFileError: if `filename` doesn't look like cifti
853
881
IOError : if `filename` does not exist
854
882
"""
855
- from .. nifti2 import load as Nifti2load
856
- return Nifti2load ( filename ). as_cifti ( )
883
+ from .parse_cifti_fast import _CiftiAsNiftiImage
884
+ return _CiftiAsNiftiImage . from_filename ( filename )
857
885
858
886
859
887
def save (img , filename ):
@@ -865,5 +893,3 @@ def save(img, filename):
865
893
filename to which to save image
866
894
"""
867
895
CiftiImage .instance_to_filename (img , filename )
868
-
869
-
0 commit comments