Interpolate source estimate data to MRI.
(stc, morph, mri_resolution, mri_space, output)
| 1037 | |
| 1038 | |
| 1039 | def _interpolate_data(stc, morph, mri_resolution, mri_space, output): |
| 1040 | """Interpolate source estimate data to MRI.""" |
| 1041 | _check_dep(nibabel="2.1.0", dipy=False) |
| 1042 | NiftiImage, NiftiHeader = _triage_output(output) |
| 1043 | _validate_type(stc, _BaseVolSourceEstimate, "stc", "volume source estimate") |
| 1044 | assert morph.kind in ("volume", "mixed") |
| 1045 | |
| 1046 | voxel_size_defined = False |
| 1047 | |
| 1048 | if isinstance(mri_resolution, int | float) and not isinstance(mri_resolution, bool): |
| 1049 | # use iso voxel size |
| 1050 | mri_resolution = (float(mri_resolution),) * 3 |
| 1051 | |
| 1052 | if isinstance(mri_resolution, tuple): |
| 1053 | _check_dep(nibabel=False, dipy="0.10.1") # nibabel was already checked |
| 1054 | from dipy.align.reslice import reslice |
| 1055 | |
| 1056 | voxel_size = mri_resolution |
| 1057 | voxel_size_defined = True |
| 1058 | mri_resolution = True |
| 1059 | |
| 1060 | # if data wasn't morphed yet - necessary for call of |
| 1061 | # stc_unmorphed.as_volume. Since only the shape of src is known, it cannot |
| 1062 | # be resliced to a given voxel size without knowing the original. |
| 1063 | if isinstance(morph, SourceSpaces): |
| 1064 | assert morph.kind in ("volume", "mixed") |
| 1065 | offset = 2 if morph.kind == "mixed" else 0 |
| 1066 | if voxel_size_defined: |
| 1067 | raise ValueError( |
| 1068 | "Cannot infer original voxel size for reslicing... " |
| 1069 | "set mri_resolution to boolean value or apply morph first." |
| 1070 | ) |
| 1071 | # Now deal with the fact that we may have multiple sub-volumes |
| 1072 | inuse = [s["inuse"] for s in morph[offset:]] |
| 1073 | src_shape = [s["shape"] for s in morph[offset:]] |
| 1074 | assert len(set(map(tuple, src_shape))) == 1 |
| 1075 | src_subject = morph._subject |
| 1076 | morph = BunchConst(src_data=_get_src_data(morph, mri_resolution)[0]) |
| 1077 | else: |
| 1078 | # Make a list as we may have many inuse when using multiple sub-volumes |
| 1079 | inuse = morph.src_data["inuse"] |
| 1080 | src_subject = morph.subject_from |
| 1081 | assert isinstance(inuse, list) |
| 1082 | if stc.subject is not None: |
| 1083 | _check_subject_src(stc.subject, src_subject, "stc.subject") |
| 1084 | |
| 1085 | n_times = stc.data.shape[1] |
| 1086 | shape = morph.src_data["src_shape"][::-1] + (n_times,) # SAR->RAST |
| 1087 | dtype = np.complex128 if np.iscomplexobj(stc.data) else np.float64 |
| 1088 | # order='F' so that F-order flattening is faster |
| 1089 | vols = np.zeros((np.prod(shape[:3]), shape[3]), dtype=dtype, order="F") |
| 1090 | n_vertices_seen = 0 |
| 1091 | for this_inuse in inuse: |
| 1092 | this_inuse = this_inuse.astype(bool) |
| 1093 | n_vertices = np.sum(this_inuse) |
| 1094 | stc_slice = slice(n_vertices_seen, n_vertices_seen + n_vertices) |
| 1095 | vols[this_inuse] = stc.data[stc_slice] |
| 1096 | n_vertices_seen += n_vertices |
no test coverage detected