def create_geometry_map(applies_to_matrix_dimension): voxels = ci.Cifti2VoxelIndicesIJK(brain_models[0][1]) left_thalamus = ci.Cifti2BrainModel(index_offset=0, index_count=4, model_type='CIFTI_MODEL_TYPE_VOXELS', brain_structure=brain_models[0][0], voxel_indices_ijk=voxels) vertices = ci.Cifti2VertexIndices(np.array(brain_models[1][1])) left_cortex = ci.Cifti2BrainModel(index_offset=4, index_count=5, model_type='CIFTI_MODEL_TYPE_SURFACE', brain_structure=brain_models[1][0], vertex_indices=vertices) left_cortex.surface_number_of_vertices = number_of_vertices vertices = ci.Cifti2VertexIndices(np.array(brain_models[2][1])) right_cortex = ci.Cifti2BrainModel(index_offset=9, index_count=1, model_type='CIFTI_MODEL_TYPE_SURFACE', brain_structure=brain_models[2][0], vertex_indices=vertices) right_cortex.surface_number_of_vertices = number_of_vertices volume = ci.Cifti2Volume( dimensions, ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, affine)) return ci.Cifti2MatrixIndicesMap( applies_to_matrix_dimension, 'CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=[left_thalamus, left_cortex, right_cortex, volume])
def create_brain_models(info): """Creates a list of brain_models from a list of MapInfo""" offset = 0 brain_models = [] structures = [] for i in info: if i.brain_structure in structures: raise Exception else: structures.append(i.brain_structure) if i.model_type == ModelType.SURFACE: vertices = ci.Cifti2VertexIndices(i.indices) brain_models.append( ci.Cifti2BrainModel( index_offset=offset, index_count=len(vertices), model_type=i.model_type, brain_structure=i.brain_structure, vertex_indices=vertices, n_surface_vertices=i.surface_number_of_vertices)) offset += len(vertices) else: voxels = ci.Cifti2VoxelIndicesIJK(i.indices) brain_models.append( ci.Cifti2BrainModel(index_offset=offset, index_count=len(voxels), model_type=i.model_type, brain_structure=i.brain_structure, voxel_indices_ijk=voxels)) offset += len(voxels) return brain_models
def to_mapping(self, dim): """ Converts the brain model axis to a MatrixIndicesMap for storage in CIFTI format Parameters ---------- dim : int which dimension of the CIFTI vector/matrix is described by this dataset (zero-based) Returns ------- cifti2.Cifti2MatrixIndicesMap """ mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_BRAIN_MODELS') for name, to_slice, bm in self.iter_structures(): is_surface = name in self.nvertices.keys() if is_surface: voxels = None vertices = cifti2.Cifti2VertexIndices(bm.vertex) nvertex = self.nvertices[name] else: voxels = cifti2.Cifti2VoxelIndicesIJK(bm.voxel) vertices = None nvertex = None if mim.volume is None: affine = cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, matrix=self.affine) mim.volume = cifti2.Cifti2Volume(self.volume_shape, affine) cifti_bm = cifti2.Cifti2BrainModel(to_slice.start, len(bm), 'CIFTI_MODEL_TYPE_SURFACE' if is_surface else 'CIFTI_MODEL_TYPE_VOXELS', name, nvertex, voxels, vertices) mim.append(cifti_bm) return mim
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
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_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)