def test_wrong_shape(): scalar_map = create_scalar_map((0, )) brain_model_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(scalar_map) matrix.append(brain_model_map) hdr = ci.Cifti2Header(matrix) # correct shape is (2, 10) for data in ( np.random.randn(1, 11), np.random.randn(2, 10, 1), np.random.randn(1, 2, 10), np.random.randn(3, 10), np.random.randn(2, 9), ): with clear_and_catch_warnings(): with error_warnings(): with pytest.raises(UserWarning): ci.Cifti2Image(data, hdr) with suppress_warnings(): img = ci.Cifti2Image(data, hdr) with pytest.raises(ValueError): img.to_file_map()
def write(filename, arr, axes): """ Saves a CIFTI file Parameters ---------- filename : str name of output CIFTI file arr : array data to be stored as vector or matrix axes : list[axis.Axis] axis explaining each of the dimensions in the arr """ arr = np.asarray(arr) if len(axes) != arr.ndim: raise ValueError( "Number of defined CIFTI axes (%i) does not match dimensionality of array (%i)" % (len(axes), arr.ndim)) for dim, ax, len_arr in zip(range(arr.ndim), axes, arr.shape): if len(ax) != len_arr: raise ValueError( "Size of CIFTI axes (%i) does not match array size (%i) for dimension %i" % (len(ax), len_arr, dim)) img = cifti2.Cifti2Image(arr, axis.to_header(axes)) img.to_filename(filename)
def test_pconnscalar(): parcel_map = create_parcel_map((0, 1)) scalar_map = create_scalar_map((2, )) matrix = ci.Cifti2Matrix() matrix.append(parcel_map) matrix.append(scalar_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(3, 3, 13) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_' 'PARCELLATED_SCALAR') with InTemporaryDirectory(): ci.save(img, 'test.pconnscalar.nii') img2 = ci.load('test.pconnscalar.nii') assert_equal(img.nifti_header.get_intent()[0], 'ConnPPSc') assert_true(isinstance(img2, ci.Cifti2Image)) assert_true((img2.get_data() == data).all()) assert_equal(img2.header.matrix.get_index_map(0), img2.header.matrix.get_index_map(1)) check_parcel_map(img2.header.matrix.get_index_map(0)) check_scalar_map(img2.header.matrix.get_index_map(2)) del img2
def yeo_to_91k(dlabel, medial_wall, reference, out): """Convert Yeo-style dlabels (Yeo and Schaefer parcellations) to 91k grayordinate space The Yeo lab generates dlabel's inclusive of medial wall vertices and only for the cortical surfaces. This is different from how typical dlabels are formatted, which exclude medial wall vertices and include voxels from all subcortical and cerebellar structures (i.e. the full 91k grayordinate space). This function corrects Yeo dlabels to proper 91k grayordinates. Parameters ---------- dlabel : str A Yeo-style .dlabel.nii atlas medial_wall : str HCP medial wall mask (.dlabel.nii) reference : str A reference .dlabel.nii file with 91k grayordinates and all brain models included out : str Output 91k grayordinate .dlabel.nii file """ dlabel = nib.load(dlabel) medial_wall = nib.load(medial_wall) ref = nib.load(reference) # remove medial wall vertices array = dlabel.get_fdata() corrected_array = array[np.logical_not(medial_wall.get_fdata())] # expand to 91k grayordinates = np.zeros(ref.shape) grayordinates[0, :corrected_array.shape[0]] = corrected_array # make header labels = dlabel.header.get_axis(index=0).label[0] label_table = ci.Cifti2LabelTable() for key, (tag, rgba) in labels.items(): label_table[key] = ci.Cifti2Label(key, tag, *rgba) maps = [ci.Cifti2NamedMap('labels', ci.Cifti2MetaData({}), label_table)] label_map = ci.Cifti2MatrixIndicesMap( applies_to_matrix_dimension=(0, ), indices_map_to_data_type='CIFTI_INDEX_TYPE_LABELS', maps=maps) model_map = ci.Cifti2MatrixIndicesMap( applies_to_matrix_dimension=(1, ), indices_map_to_data_type='CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=list(ref.header.get_index_map(1).brain_models)) model_map.volume = ref.header.get_index_map(1).volume matrix = ci.Cifti2Matrix() matrix.append(label_map) matrix.append(model_map) hdr = ci.Cifti2Header(matrix) out_dtseries = ci.Cifti2Image(grayordinates, hdr) out_dtseries.to_filename(out) return out
def write_graph_to_pscalar(graph_metric, fn): '''write parcel-wise graph metric to a parcel cifiti data for visuliziation assuming using the Cole 718 parcel''' tempcifti = nib.load( '/home/kahwang/bin/ColeAnticevicNetPartition/tempate.pscalar.nii') tempscalar = tempcifti.get_data() tempscalar[0, :] = graph_metric tempcifti = cifti2.Cifti2Image(tempscalar, tempcifti.get_header()) nib.save(tempcifti, fn)
def dlabel_to_dtseries(dlabel, out, n=10): """Create a mock .dtseries.nii from an .dlabel file All timepoints (rows) in .dtseries.nii are duplicates of the .dlabel array. This enables a way to verify that expected data is correctly extracted (e.g., label 1 should extract a timeseries of all 1's, etc). Parameters ---------- dlabel : str File name of a .dlabel.nii file out : str File name of output .dtseries.nii n : int, optional Number of timepoints to generate, by default 100 """ dlabel = nib.load(dlabel) # imitate data with TR=2 label_array = dlabel.get_fdata().ravel() tseries = np.tile(label_array, (n, 1)) data_map = ci.Cifti2MatrixIndicesMap( applies_to_matrix_dimension=(0, ), indices_map_to_data_type='CIFTI_INDEX_TYPE_SERIES', number_of_series_points=tseries.shape[0], series_start=0, series_step=2, series_exponent=0, series_unit='SECOND') # take brain models from dlabel model_map = ci.Cifti2MatrixIndicesMap( applies_to_matrix_dimension=(1, ), indices_map_to_data_type='CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=list(dlabel.header.get_index_map(1).brain_models)) volume = dlabel.header.get_index_map(1).volume if volume is not None: model_map.volume = dlabel.header.get_index_map(1).volume # make header matrix = ci.Cifti2Matrix() matrix.append(data_map) matrix.append(model_map) hdr = ci.Cifti2Header(matrix) out_dtseries = ci.Cifti2Image(tseries, hdr) out_dtseries.to_filename(out) return out
def test_pconn(): mapping = create_parcel_map((0, 1)) matrix = ci.Cifti2Matrix() matrix.append(mapping) hdr = ci.Cifti2Header(matrix) data = np.random.randn(3, 3) img = ci.Cifti2Image(data, hdr) with InTemporaryDirectory(): ci.save(img, 'test.pconn.nii') img2 = ci.load('test.pconn.nii') assert_true((img2.get_data() == data).all()) assert_equal(img2.header.matrix.get_index_map(0), img2.header.matrix.get_index_map(1)) check_parcel_map(img2.header.matrix.get_index_map(0)) del img2
def test_dscalar(): scalar_map = create_scalar_map((0, )) geometry_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(scalar_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 9) img = ci.Cifti2Image(data, hdr) with InTemporaryDirectory(): ci.save(img, 'test.dscalar.nii') img2 = ci.load('test.dscalar.nii') assert_true((img2.get_data() == data).all()) check_scalar_map(img2.header.matrix.get_index_map(0)) check_geometry_map(img2.header.matrix.get_index_map(1)) del img2
def test_plabel(): label_map = create_label_map((0, )) parcel_map = create_parcel_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(label_map) matrix.append(parcel_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 3) img = ci.Cifti2Image(data, hdr) with InTemporaryDirectory(): ci.save(img, 'test.plabel.nii') img2 = ci.load('test.plabel.nii') assert_true((img2.get_data() == data).all()) check_label_map(img2.header.matrix.get_index_map(0)) check_parcel_map(img2.header.matrix.get_index_map(1)) del img2
def dlabel_atlas_to_mask(dlabel, label, out): """Convert an atlas to a single region (i.e. binary) mask Parameters ---------- dlabel : str File name of a .dlabel.nii file label : int Numeric label for region of interest out : str File name of output .dlabel.nii """ dlabel = nib.load(dlabel) arr = dlabel.get_fdata() mask = np.where(arr == label, label, 0) mask_img = ci.Cifti2Image(mask, header=dlabel.header) mask_img.to_filename(out) return out
def test_pconn(): mapping = create_parcel_map((0, 1)) matrix = ci.Cifti2Matrix() matrix.append(mapping) hdr = ci.Cifti2Header(matrix) data = np.random.randn(4, 4) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED') with InTemporaryDirectory(): ci.save(img, 'test.pconn.nii') img2 = ci.load('test.pconn.nii') assert img.nifti_header.get_intent()[0] == 'ConnParcels' assert isinstance(img2, ci.Cifti2Image) assert_array_equal(img2.get_fdata(), data) assert img2.header.matrix.get_index_map( 0) == img2.header.matrix.get_index_map(1) check_parcel_map(img2.header.matrix.get_index_map(0)) del img2
def test_dconn(): mapping = create_geometry_map((0, 1)) matrix = ci.Cifti2Matrix() matrix.append(mapping) hdr = ci.Cifti2Header(matrix) data = np.random.randn(9, 9) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE') with InTemporaryDirectory(): ci.save(img, 'test.dconn.nii') img2 = nib.load('test.dconn.nii') assert_equal(img2.nifti_header.get_intent()[0], 'ConnDense') assert_true(isinstance(img2, ci.Cifti2Image)) assert_true((img2.get_data() == data).all()) assert_equal(img2.header.matrix.get_index_map(0), img2.header.matrix.get_index_map(1)) check_geometry_map(img2.header.matrix.get_index_map(0)) del img2
def test_plabel(): label_map = create_label_map((0, )) parcel_map = create_parcel_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(label_map) matrix.append(parcel_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 4) img = ci.Cifti2Image(data, hdr) with InTemporaryDirectory(): ci.save(img, 'test.plabel.nii') img2 = ci.load('test.plabel.nii') assert img.nifti_header.get_intent()[0] == 'ConnUnknown' assert isinstance(img2, ci.Cifti2Image) assert_array_equal(img2.get_fdata(), data) check_label_map(img2.header.matrix.get_index_map(0)) check_parcel_map(img2.header.matrix.get_index_map(1)) del img2
def test_pdconn(): geometry_map = create_geometry_map((0, )) parcel_map = create_parcel_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(geometry_map) matrix.append(parcel_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(10, 4) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_DENSE') with InTemporaryDirectory(): ci.save(img, 'test.pdconn.nii') img2 = ci.load('test.pdconn.nii') assert img2.nifti_header.get_intent()[0] == 'ConnParcelDense' assert isinstance(img2, ci.Cifti2Image) assert_array_equal(img2.get_fdata(), data) check_geometry_map(img2.header.matrix.get_index_map(0)) check_parcel_map(img2.header.matrix.get_index_map(1)) del img2
def test_ptseries(): series_map = create_series_map((0, )) parcel_map = create_parcel_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(series_map) matrix.append(parcel_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(13, 3) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SERIES') with InTemporaryDirectory(): ci.save(img, 'test.ptseries.nii') img2 = nib.load('test.ptseries.nii') assert_equal(img2.nifti_header.get_intent()[0], 'ConnParcelSries') assert_true(isinstance(img2, ci.Cifti2Image)) assert_true((img2.get_data() == data).all()) check_series_map(img2.header.matrix.get_index_map(0)) check_parcel_map(img2.header.matrix.get_index_map(1)) del img2
def test_pscalar(): scalar_map = create_scalar_map((0, )) parcel_map = create_parcel_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(scalar_map) matrix.append(parcel_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 4) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_PARCELLATED_SCALAR') with InTemporaryDirectory(): ci.save(img, 'test.pscalar.nii') img2 = nib.load('test.pscalar.nii') assert img2.nifti_header.get_intent()[0] == 'ConnParcelScalr' assert isinstance(img2, ci.Cifti2Image) assert_array_equal(img2.get_fdata(), data) check_scalar_map(img2.header.matrix.get_index_map(0)) check_parcel_map(img2.header.matrix.get_index_map(1)) del img2
def test_dlabel(): label_map = create_label_map((0, )) geometry_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(label_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 10) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_LABELS') with InTemporaryDirectory(): ci.save(img, 'test.dlabel.nii') img2 = nib.load('test.dlabel.nii') assert img2.nifti_header.get_intent()[0] == 'ConnDenseLabel' assert isinstance(img2, ci.Cifti2Image) assert_array_equal(img2.get_fdata(), data) check_label_map(img2.header.matrix.get_index_map(0)) check_geometry_map(img2.header.matrix.get_index_map(1)) del img2
def test_dtseries(): series_map = create_series_map((0, )) geometry_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(series_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(13, 10) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES') with InTemporaryDirectory(): ci.save(img, 'test.dtseries.nii') img2 = nib.load('test.dtseries.nii') assert_equal(img2.nifti_header.get_intent()[0], 'ConnDenseSeries') assert_true(isinstance(img2, ci.Cifti2Image)) assert_array_equal(img2.get_fdata(), data) check_series_map(img2.header.matrix.get_index_map(0)) check_geometry_map(img2.header.matrix.get_index_map(1)) del img2
def test_dpconn(): parcel_map = create_parcel_map((0, )) geometry_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(parcel_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 3) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_PARCELLATED') with InTemporaryDirectory(): ci.save(img, 'test.dpconn.nii') img2 = ci.load('test.dpconn.nii') assert_equal(img2.nifti_header.get_intent()[0], 'ConnDenseParcel') assert_true(isinstance(img2, ci.Cifti2Image)) assert_true((img2.get_data() == data).all()) check_parcel_map(img2.header.matrix.get_index_map(0)) check_geometry_map(img2.header.matrix.get_index_map(1)) del img2
def test_dscalar(): scalar_map = create_scalar_map((0, )) geometry_map = create_geometry_map((1, )) matrix = ci.Cifti2Matrix() matrix.append(scalar_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) data = np.random.randn(2, 9) img = ci.Cifti2Image(data, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SCALARS') with InTemporaryDirectory(): ci.save(img, 'test.dscalar.nii') img2 = nib.load('test.dscalar.nii') assert_equal(img2.nifti_header.get_intent()[0], 'ConnDenseScalar') assert_true(isinstance(img2, ci.Cifti2Image)) assert_true((img2.get_data() == data).all()) check_scalar_map(img2.header.matrix.get_index_map(0)) check_geometry_map(img2.header.matrix.get_index_map(1)) del img2
def run_from_args(args): """ Runs the script based on a Namespace containing the command line arguments """ logger.info('starting %s', op.basename(__file__)) dconn1 = cifti2.load(args.input) axes1 = dconn1.header.get_axis(dconn1) dconn2 = cifti2.load(args.reference) axes2 = dconn2.header.get_axis(dconn2) if not (isinstance(axes1[1], cifti2.BrainModelAxis) or isinstance(axes1[1], cifti2.ParcelsAxis)): raise ValueError("Columns should have greyordinates or parcels") if axes1[1] != axes2[1]: raise ValueError( "Compared CIFTI files should have the same greyordinates/parcels along the columns" ) if args.as_dconn: if isinstance(axes1[0], cifti2.SeriesAxis): axes1 = (axes1[1], ) * 2 dconn1 = FakeDConn(dconn1) elif isinstance(axes2[0], cifti2.SeriesAxis): axes2 = (axes2[1], ) * 2 dconn2 = FakeDConn(dconn2) if args.split_dconn and not isinstance(axes1[0], cifti2.BrainModelAxis): raise ValueError( "Rows should be greyordinates when using the option --split_dconn") if axes1[0] != axes2[0]: raise ValueError( "Compared CIFTI files should have the same features along the rows" ) as_dict = run( dconn1=dconn1, dconn2=dconn2, split_greyordinates=axes1[0] if args.split_dconn else None, ) scalar = cifti2.ScalarAxis(list(as_dict.keys())) arr = np.stack(list(as_dict.values()), -1) cifti2.Cifti2Image(arr.T, header=(scalar, axes1[1])).to_filename(args.output) logger.info('ending %s', op.basename(__file__))
def writer(obj): """ Writes given object to the file. Can be one of: - Nifti1Image (for NIFTI/CIFTI output) - array/axes tuple (for any output) - tuple with 2 surface arrays (for GIFTI/CIFTI output) :param obj: input object """ if not isinstance(obj, tuple): # NIFTI Image if format == 'GIFTI': raise ValueError( f"Can not write volumetric image {obj} to GIFTI path {path}" ) elif format == 'NIFTI': obj.to_filename(path) else: arr, axes = _nifti2cifti(obj) cifti2.Cifti2Image(arr, header=axes).to_filename(path) return part1, part2 = obj if isinstance(part2, np.ndarray): # surface arrays if format == 'NIFTI': raise ValueError( f"Can not write surface array to NIFTI path {path}") elif format == 'GIFTI': if part1.size == 0 and part2.size == 0: raise ValueError("Only empty surface arrays provided") if part1.size == 0 or part2.size == 0: if '@' in path: raise ValueError( "Single surface array provided to 2 GIFTI files") if part1.size == 0: write_gifti(path, [part2], 'CortexRight') else: write_gifti(path, [part1], 'CortexLeft') else: fn1, fn2 = path.split('@') write_gifti(fn1, [part1], 'CortexLeft') write_gifti(fn2, [part2], 'CortexRight') else: arr, axes = _gifti2cifti(part1, part2) cifti2.Cifti2Image(arr, header=axes).to_filename(path) elif isinstance(part1, tuple): # surface labels arr1, table1 = part1 arr2, table2 = part2 if format == 'NIFTI': raise ValueError( f"Can not write surface array to NIFTI path {path}") elif format == 'GIFTI': if arr1.size == 0 and arr2.size == 0: raise ValueError("Only empty surface arrays provided") if arr1.size == 0 or arr2.size == 0: if '@' in path: raise ValueError( "Single surface array provided to 2 GIFTI files") if arr1.size == 0: write_gifti(path, [arr2], 'CortexRight', color_map=table2) else: write_gifti(path, [arr1], 'CortexLeft', color_map=table1) else: fn1, fn2 = path.split('@') write_gifti(fn1, [arr1], 'CortexLeft', color_map=table1) write_gifti(fn2, [arr2], 'CortexRight', color_map=table2) else: if table1 != table2: raise ValueError( "Label tables should be the same for both surfaces to " + "combine into single CIFTI file") arr, axes = _gifti2cifti(arr1, arr2, table=table1) cifti2.Cifti2Image(arr, header=axes).to_filename(path) else: if format == 'CIFTI': cifti2.Cifti2Image(part1, header=part2).to_filename(path) elif format == 'NIFTI': _cifti2nifti(part1, part2).to_filename(path) else: try: (a1, a2), table = _cifti2gifti(part1, part2, get_label=True) as_gifti = ((a1, table), (a2, table)) except ValueError: as_gifti = _cifti2gifti(part1, part2) writer(as_gifti)
def _create_cifti_image(bold_file, label_file, annotation_files, gii_files, volume_target, surface_target, tr): """ Generate CIFTI image in target space Parameters bold_file : 4D BOLD timeseries label_file : label atlas annotation_files : FreeSurfer annotations gii_files : 4D BOLD surface timeseries in GIFTI format volume_target : label atlas space surface_target : gii_files space tr : repetition timeseries Returns out_file : BOLD data as CIFTI dtseries """ label_img = nb.load(label_file) bold_img = resample_to_img(bold_file, label_img) bold_data = bold_img.get_data() timepoints = bold_img.shape[3] label_data = label_img.get_data() # set up CIFTI information series_map = ci.Cifti2MatrixIndicesMap( (0, ), 'CIFTI_INDEX_TYPE_SERIES', number_of_series_points=timepoints, series_exponent=0, series_start=0.0, series_step=tr, series_unit='SECOND') # Create CIFTI brain models idx_offset = 0 brainmodels = [] bm_ts = np.empty((timepoints, 0)) for structure, labels in CIFTI_STRUCT_WITH_LABELS.items(): if labels is None: # surface model model_type = "CIFTI_MODEL_TYPE_SURFACE" # use the corresponding annotation hemi = structure.split('_')[-1] annot = nb.freesurfer.read_annot( annotation_files[hemi == "RIGHT"]) # currently only supports L/R cortex gii = nb.load(gii_files[hemi == "RIGHT"]) # calculate total number of vertices surf_verts = len(annot[0]) # remove medial wall for CIFTI format vert_idx = np.nonzero( annot[0] != annot[2].index(b'unknown'))[0] # extract values across volumes ts = np.array([tsarr.data[vert_idx] for tsarr in gii.darrays]) vert_idx = ci.Cifti2VertexIndices(vert_idx) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vert_idx), model_type=model_type, brain_structure=structure, vertex_indices=vert_idx, n_surface_vertices=surf_verts) bm_ts = np.column_stack((bm_ts, ts)) idx_offset += len(vert_idx) brainmodels.append(bm) else: model_type = "CIFTI_MODEL_TYPE_VOXELS" vox = [] ts = None for label in labels: ijk = np.nonzero(label_data == label) ts = (bold_data[ijk] if ts is None else np.concatenate( (ts, bold_data[ijk]))) vox += [[ijk[0][ix], ijk[1][ix], ijk[2][ix]] for ix, row in enumerate(ts)] bm_ts = np.column_stack((bm_ts, ts.T)) vox = ci.Cifti2VoxelIndicesIJK(vox) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vox), model_type=model_type, brain_structure=structure, voxel_indices_ijk=vox) idx_offset += len(vox) brainmodels.append(bm) volume = ci.Cifti2Volume( bold_img.shape[:3], ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ( -3, bold_img.affine)) brainmodels.append(volume) # create CIFTI geometry based on brainmodels geometry_map = ci.Cifti2MatrixIndicesMap( (1, ), 'CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=brainmodels) # provide some metadata to CIFTI matrix meta = { "target_surface": surface_target, "target_volume": volume_target, } # generate and save CIFTI image matrix = ci.Cifti2Matrix() matrix.append(series_map) matrix.append(geometry_map) matrix.metadata = ci.Cifti2MetaData(meta) hdr = ci.Cifti2Header(matrix) img = ci.Cifti2Image(bm_ts, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES') _, out_base, _ = split_filename(bold_file) out_file = "{}.dtseries.nii".format(out_base) ci.save(img, out_file) return os.path.join(os.getcwd(), out_file)
def _create_dtseries_cifti(timepoints, models): """Create a dense timeseries CIFTI-2 file""" import nibabel.cifti2 as ci def create_series_map(): return ci.Cifti2MatrixIndicesMap((0, ), 'CIFTI_INDEX_TYPE_SERIES', number_of_series_points=timepoints, series_exponent=0, series_start=0, series_step=1, series_unit='SECOND') def create_geometry_map(): index_offset = 0 brain_models = [] timeseries = np.zeros((timepoints, 0)) for name, data in models: if "CORTEX" in name: model_type = "CIFTI_MODEL_TYPE_SURFACE" attr = "vertex_indices" indices = ci.Cifti2VertexIndices(np.arange(len(data))) else: model_type = "CIFTI_MODEL_TYPE_VOXELS" attr = "voxel_indices_ijk" indices = ci.Cifti2VoxelIndicesIJK(np.arange(len(data))) bm = ci.Cifti2BrainModel( index_offset=index_offset, index_count=len(data), model_type=model_type, brain_structure=name, ) setattr(bm, attr, indices) index_offset += len(data) brain_models.append(bm) timeseries = np.column_stack((timeseries, data.T)) brain_models.append( ci.Cifti2Volume( (4, 4, 4), ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ( -3, np.eye(4)), )) return ci.Cifti2MatrixIndicesMap( (1, ), "CIFTI_INDEX_TYPE_BRAIN_MODELS", maps=brain_models, ), timeseries matrix = ci.Cifti2Matrix() series_map = create_series_map() geometry_map, ts = create_geometry_map() matrix.append(series_map) matrix.append(geometry_map) hdr = ci.Cifti2Header(matrix) img = ci.Cifti2Image(dataobj=ts, header=hdr) img.nifti_header.set_intent("NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES") out_file = Path("test.dtseries.nii").absolute() ci.save(img, out_file) return out_file
def _create_cifti_image(bold_file, label_file, bold_surfs, annotation_files, tr, targets): """ Generate CIFTI image in target space. Parameters ---------- bold_file : str BOLD volumetric timeseries label_file : str Subcortical label file bold_surfs : list BOLD surface timeseries [L,R] annotation_files : list Surface label files used to remove medial wall tr : float BOLD repetition time targets : tuple or list Surface and volumetric output spaces Returns ------- out : BOLD data saved as CIFTI dtseries """ bold_img = nb.load(bold_file) label_img = nb.load(label_file) if label_img.shape != bold_img.shape[:3]: warnings.warn("Resampling bold volume to match label dimensions") bold_img = resample_to_img(bold_img, label_img) bold_data = bold_img.get_fdata(dtype='float32') timepoints = bold_img.shape[3] label_data = np.asanyarray(label_img.dataobj).astype('int16') # Create brain models idx_offset = 0 brainmodels = [] bm_ts = np.empty((timepoints, 0)) for structure, labels in CIFTI_STRUCT_WITH_LABELS.items(): if labels is None: # surface model model_type = "CIFTI_MODEL_TYPE_SURFACE" # use the corresponding annotation hemi = structure.split('_')[-1] # currently only supports L/R cortex surf = nb.load(bold_surfs[hemi == "RIGHT"]) surf_verts = len(surf.darrays[0].data) if annotation_files[0].endswith('.annot'): annot = nb.freesurfer.read_annot( annotation_files[hemi == "RIGHT"]) # remove medial wall medial = np.nonzero(annot[0] != annot[2].index(b'unknown'))[0] else: annot = nb.load(annotation_files[hemi == "RIGHT"]) medial = np.nonzero(annot.darrays[0].data)[0] # extract values across volumes ts = np.array([tsarr.data[medial] for tsarr in surf.darrays]) vert_idx = ci.Cifti2VertexIndices(medial) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vert_idx), model_type=model_type, brain_structure=structure, vertex_indices=vert_idx, n_surface_vertices=surf_verts) idx_offset += len(vert_idx) bm_ts = np.column_stack((bm_ts, ts)) else: model_type = "CIFTI_MODEL_TYPE_VOXELS" vox = [] ts = None for label in labels: ijk = np.nonzero(label_data == label) if ijk[0].size == 0: # skip label if nothing matches continue ts = (bold_data[ijk] if ts is None else np.concatenate( (ts, bold_data[ijk]))) vox += [[ijk[0][ix], ijk[1][ix], ijk[2][ix]] for ix, row in enumerate(ts)] vox = ci.Cifti2VoxelIndicesIJK(vox) bm = ci.Cifti2BrainModel(index_offset=idx_offset, index_count=len(vox), model_type=model_type, brain_structure=structure, voxel_indices_ijk=vox) idx_offset += len(vox) bm_ts = np.column_stack((bm_ts, ts.T)) # add each brain structure to list brainmodels.append(bm) # add volume information brainmodels.append( ci.Cifti2Volume( bold_img.shape[:3], ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ( -3, bold_img.affine))) # generate Matrix information series_map = ci.Cifti2MatrixIndicesMap((0, ), 'CIFTI_INDEX_TYPE_SERIES', number_of_series_points=timepoints, series_exponent=0, series_start=0.0, series_step=tr, series_unit='SECOND') geometry_map = ci.Cifti2MatrixIndicesMap((1, ), 'CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=brainmodels) # provide some metadata to CIFTI matrix meta = { "surface": targets[0], "volume": targets[1], } # generate and save CIFTI image matrix = ci.Cifti2Matrix() matrix.append(series_map) matrix.append(geometry_map) matrix.metadata = ci.Cifti2MetaData(meta) hdr = ci.Cifti2Header(matrix) img = ci.Cifti2Image(bm_ts, hdr) img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES') out_file = "{}.dtseries.nii".format(split_filename(bold_file)[1]) ci.save(img, out_file) return os.path.join(os.getcwd(), out_file)
<https://github.com/nipy/nibabel/issues/758> ''' import numpy as np import nibabel.cifti2 as ci # Select the folder containing your *.dlabel.nii file import os os.chdir(MAIN_FOLDER) label_filename = 'Q1-Q6_RelatedParcellation210.CorticalAreas_dil_Final_Final_Areas_Group_Colors.32k_fs_LR.dlabel.nii' # Define the rgba for the new labels. This toy example sets every grayordinate to gray new_labels = {0: ('0', (1., 1., 1., 0.))} for i in np.arange(0, 360): new_labels[i + 1] = (str(i + 1), (0.5, 0.5, 0.5, 1.)) img = ci.Cifti2Image.from_filename(label_filename) # extracting the Axis describing the labels (i.e., along the first dimension) label_axis = img.header.get_axis(0) # updating the labels for the first (in this case only) column label_axis.label[0] = new_labels # Create a new header with new labels across the first axis and the original brain model with the vertices across the other axis. new_header = ci.Cifti2Header.from_axes((label_axis, img.header.get_axis(1))) # Create a new *.dlabel.nii file containing the new colors included in the new_header new_img = ci.Cifti2Image(img.get_fdata(), header=new_header) new_img.to_filename('new_labels.dlabel.nii')
file.close() volume_coords = coords[coords[:, 3] >= 2] #load subcortical seed volume subcortical_vol = nib.load(subcortical_path) subcortical_roi = subcortical_vol.get_data() #load gifti ROIs roi_left = nib.load(roi_path_l).darrays[0].data != 0 roi_right = nib.load(roi_path_r).darrays[0].data != 0 #set up cifti brain model axes bm_ctx_left = cifti2.BrainModelAxis.from_mask(roi_left, name="CortexLeft") bm_ctx_right = cifti2.BrainModelAxis.from_mask(roi_right, name="CortexRight") bm_subcortical = cifti2.BrainModelAxis.from_mask(subcortical_roi, affine=subcortical_vol.affine, name="other") bm_subcortical.voxel = volume_coords[:, :3] bm = bm_ctx_left + bm_ctx_right + bm_subcortical sc = cifti2.ScalarAxis(np.arange(n_comp).astype("str")) #save cifti hdr = cifti2.Cifti2Header.from_axes((sc, bm)) img = cifti2.Cifti2Image(components.T, hdr) new_fname = os.path.splitext(component_path)[0] + ".dscalar.nii" nib.save(img, new_fname)
def create_img(maps, data): matrix = ci.Cifti2Matrix() matrix.extend(maps) hdr = ci.Cifti2Header(matrix) img = ci.Cifti2Image(data, hdr) return img