@@ -881,6 +881,51 @@ def set_data_shape(self, shape):
881
881
shape = (- 1 , 1 , 1 ) + shape [3 :]
882
882
super (Nifti1Header , self ).set_data_shape (shape )
883
883
884
+ def set_data_dtype (self , datatype ):
885
+ """ Set numpy dtype for data from code or dtype or type
886
+
887
+ Using :py:class:`int` or ``"int"`` is disallowed, as these types
888
+ will be interpreted as ``np.int64``, which is almost never desired.
889
+ ``np.int64`` is permitted for those intent on making poor choices.
890
+
891
+ Examples
892
+ --------
893
+ >>> hdr = Nifti1Header()
894
+ >>> hdr.set_data_dtype(np.uint8)
895
+ >>> hdr.get_data_dtype()
896
+ dtype('uint8')
897
+ >>> hdr.set_data_dtype(np.dtype(np.uint8))
898
+ >>> hdr.get_data_dtype()
899
+ dtype('uint8')
900
+ >>> hdr.set_data_dtype('implausible') #doctest: +IGNORE_EXCEPTION_DETAIL
901
+ Traceback (most recent call last):
902
+ ...
903
+ HeaderDataError: data dtype "implausible" not recognized
904
+ >>> hdr.set_data_dtype('none') #doctest: +IGNORE_EXCEPTION_DETAIL
905
+ Traceback (most recent call last):
906
+ ...
907
+ HeaderDataError: data dtype "none" known but not supported
908
+ >>> hdr.set_data_dtype(np.void) #doctest: +IGNORE_EXCEPTION_DETAIL
909
+ Traceback (most recent call last):
910
+ ...
911
+ HeaderDataError: data dtype "<type 'numpy.void'>" known but not supported
912
+ >>> hdr.set_data_dtype('int')
913
+ Traceback (most recent call last):
914
+ ...
915
+ ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
916
+ >>> hdr.set_data_dtype(int)
917
+ Traceback (most recent call last):
918
+ ...
919
+ ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
920
+ >>> hdr.set_data_dtype('int64')
921
+ >>> hdr.get_data_dtype()
922
+ dtype('int64')
923
+ """
924
+ if not isinstance (datatype , np .dtype ) and datatype in (int , "int" ):
925
+ raise ValueError (f"Invalid data type { datatype !r} . Specify a sized integer, "
926
+ "e.g., 'uint8' or numpy.int16." )
927
+ super ().set_data_dtype (datatype )
928
+
884
929
def get_qform_quaternion (self ):
885
930
""" Compute quaternion from b, c, d of quaternion
886
931
@@ -1755,6 +1800,13 @@ class Nifti1Pair(analyze.AnalyzeImage):
1755
1800
1756
1801
def __init__ (self , dataobj , affine , header = None ,
1757
1802
extra = None , file_map = None , dtype = None ):
1803
+ # Special carve-out for 64 bit integers
1804
+ # See GitHub issues
1805
+ # * https://github.com/nipy/nibabel/issues/1046
1806
+ # * https://github.com/nipy/nibabel/issues/1089
1807
+ # This only applies to NIfTI because the parent Analyze formats did
1808
+ # not support 64-bit integer data, so `set_data_dtype(int64)` would
1809
+ # already fail.
1758
1810
danger_dts = (np .dtype ("int64" ), np .dtype ("uint64" ))
1759
1811
if header is None and dtype is None and dataobj .dtype in danger_dts :
1760
1812
msg = (f"Image data has type { dataobj .dtype } , which may cause "
0 commit comments