Exemple #1
0
def xmain(bids_dir, freesurfer_dir, acquisition='clinical', noparallel=False):
    """
    assign electrodes to brain regions',

    Parameters
    ----------
    bids_dir : path

    freesurfer_dir : path

    acquisition : str
        acquisition type of the electrode files
    noparallel : bool
        if it should run serially (i.e. not parallely, mostly for debugging)
    """
    args = []
    for electrode_path in find_in_bids(bids_dir,
                                       generator=True,
                                       acquisition=acquisition,
                                       modality='electrodes',
                                       extension='.tsv'):
        elec = Electrodes(electrode_path)
        fs = Freesurfer(freesurfer_dir / ('sub-' + elec.subject))
        args.append((elec, fs))

    if noparallel:
        for arg in args:
            assign_regions(*arg)
    else:
        with Pool(processes=4) as p:
            p.starmap(assign_regions, args)
Exemple #2
0
def calc_fmri_at_elec(measure_nii, electrodes_file, distance, kernels,
                      graymatter, output_dir):
    """
    Calculate the (weighted) average of fMRI values at electrode locations
    """
    electrodes = Electrodes(electrodes_file)

    img = nload(str(measure_nii))
    mri = img.get_data()
    mri[mri == 0] = NaN

    labels = electrodes.electrodes.get(map_lambda=lambda x: x['name'])
    chan_xyz = array(electrodes.get_xyz())

    nd = array(list(ndindex(mri.shape)))
    ndi = from_mrifile_to_chan(img, nd)

    if graymatter:
        gm_mri = nload(str(graymatter)).get_data().astype(bool)
        mri[~gm_mri] = NaN

    lg.debug(
        f'Computing fMRI values for {measure_nii.name} at {len(labels)} electrodes and {len(kernels)} "{distance}" kernels'
    )
    fmri_vals, n_voxels = compute_kernels(kernels, chan_xyz, mri, ndi,
                                          distance)

    fmri_vals_tsv = output_dir / replace_underscore(measure_nii.name,
                                                    'compare.tsv')
    n_voxels_tsv = output_dir / replace_underscore(measure_nii.name,
                                                   'nvoxels.tsv')

    with fmri_vals_tsv.open('w') as f:
        f.write('channel\t' + '\t'.join(str(one_k)
                                        for one_k in kernels) + '\n')
        for one_label, val_at_elec in zip(labels, fmri_vals):
            f.write(one_label + '\t' +
                    '\t'.join(str(one_val) for one_val in val_at_elec) + '\n')

    with n_voxels_tsv.open('w') as f:
        f.write('channel\t' + '\t'.join(str(one_k)
                                        for one_k in kernels) + '\n')
        for one_label, val_at_elec in zip(labels, n_voxels):
            f.write(one_label + '\t' +
                    '\t'.join(str(one_val) for one_val in val_at_elec) + '\n')

    return fmri_vals_tsv, n_voxels_tsv
Exemple #3
0
def read_ieeg_block(filename, electrode_file, conditions, minimalduration,
                    output_dir):
    d = Dataset(filename, bids=True)
    markers = d.read_markers()

    electrodes = Electrodes(electrode_file)
    elec_names = [x['name'] for x in electrodes.electrodes.tsv]
    elec_names = [x for x in elec_names if x in d.header['chan_name']
                  ]  # exclude elec location that have no corresponding channel

    all_conditions = [x for v in conditions.values() for x in v]
    clean_labels = _reject_channels(d, elec_names, all_conditions,
                                    minimalduration)

    outputs = []
    for active_baseline, data_conds in conditions.items():
        block_beg = []
        block_end = []

        for mrk in markers:

            if mrk['name'] in data_conds:
                dur = (mrk['end'] - mrk['start'])
                if dur >= minimalduration:
                    block_beg.append(mrk['start'])
                    block_end.append(mrk['end'])

        data = d.read_data(begtime=block_beg,
                           endtime=block_end,
                           chan=clean_labels)

        output_task = Task(filename)
        output_task.extension = '.pkl'
        output_task.task += active_baseline
        output_file = output_dir / output_task.get_filename()
        with output_file.open('wb') as f:
            dump(data, f)
        outputs.append(output_file)

    return outputs
Exemple #4
0
def assign_regions(elec, freesurfer):
    bids_dir = find_root(elec.filename)
    elec.acquisition += 'regions'
    tsv_electrodes = elec.get_filename(bids_dir)

    with tsv_electrodes.open('w') as f:
        f.write('name\tx\ty\tz\ttype\tsize\tmaterial\tregion\n'
                )  # TODO: region is not in BEP010
        for _tsv in elec.electrodes.tsv:
            xyz = array([float(_tsv['x']), float(_tsv['y']), float(_tsv['z'])])
            region = freesurfer.find_brain_region(
                xyz, exclude_regions=('White', 'WM', 'Unknown'))[0]
            f.write(
                f'{_tsv["name"]}\t{_tsv["x"]}\t{_tsv["y"]}\t{_tsv["z"]}\t{_tsv["type"]}\t{_tsv["size"]}\t{_tsv["material"]}\t{region}\n'
            )

    elec.coordframe.json[
        'iEEGCoordinateProcessingDescription'] += '; Assign brain regions'  # TODO: better description + remove None
    new_json = replace_underscore(tsv_electrodes, 'coordsystem.json')
    with new_json.open('w') as f:
        dump(elec.coordframe.json, f, indent=2)

    return Electrodes(tsv_electrodes)
Exemple #5
0
def xmain(bids_dir,
          analysis_dir,
          freesurfer_dir,
          output_dir,
          acquisition='clinical',
          measure_modality="",
          measure_column=""):
    """
    plot electrodes onto the brain surface,

    Parameters
    ----------
    bids_dir : path

    analysis_dir : path

    freesurfer_dir : path

    output_dir : path

    acquisition : str
        acquisition type of the electrode files
    measure_modality : str
        modality
    measure_column : str
        column
    """
    img_dir = output_dir / ELECSURF_DIR
    rmtree(img_dir, ignore_errors=True)
    img_dir.mkdir(exist_ok=True, parents=True)

    for electrode_path in find_in_bids(bids_dir,
                                       generator=True,
                                       acquisition=acquisition,
                                       modality='electrodes',
                                       extension='.tsv'):
        lg.debug(f'Reading electrodes from {electrode_path}')
        elec = Electrodes(electrode_path)
        fs = Freesurfer(freesurfer_dir / ('sub-' + elec.subject))

        labels = None
        if measure_modality != "":
            try:
                ecog_file = find_in_bids(analysis_dir,
                                         subject=elec.subject,
                                         modality=measure_modality,
                                         extension='.tsv')
            except FileNotFoundError as err:
                lg.warning(err)
                continue

            lg.debug(f'Reading {measure_column} from {ecog_file}')
            ecog_tsv = read_tsv(ecog_file)

            labels = [x['name'] for x in elec.electrodes.tsv]
            labels, vals = read_channels(ecog_tsv, labels, measure_column)

        else:
            vals = None

        v = plot_electrodes(elec, fs, labels, vals)

        png_file = img_dir / replace_underscore(elec.get_filename(),
                                                'surfaceplot.png')
        lg.debug(f'Saving electrode plot on {png_file}')
        v.save(png_file)
        v.close()
Exemple #6
0
def plot_surface(parameters, frequency_band, subject, surf):

    elec_file = get_path(parameters, 'elec', subject=subject)
    ieeg_file = get_path(parameters,
                         'ieeg_tsv',
                         frequency_band=frequency_band,
                         subject=subject)
    fmri_file = get_path(parameters, 'fmri_nii', subject=subject)
    if elec_file is None or ieeg_file is None or fmri_file is None:
        return

    freesurfer_dir = parameters['paths'][
        'freesurfer_subjects_dir'] / f'sub-{subject}'

    compare_ieeg = read_tsv(ieeg_file)
    fs = Freesurfer(freesurfer_dir)
    electrodes = Electrodes(elec_file)

    elec = electrodes.electrodes.tsv
    all_elec = []
    labels = []
    for chan in compare_ieeg:
        i_chan = where(elec['name'] == chan['channel'])[0]
        all_elec.append(elec[i_chan])
        labels.append(f"{chan['channel']} = {chan['measure']:0.3f}")

    elec = concatenate(all_elec)

    if mean(elec['x']) > 0:
        right_or_left = 1
        hemi = 'rh'
    else:
        right_or_left = -1
        hemi = 'lh'

    fs = Freesurfer(freesurfer_dir)
    pial = getattr(fs.read_brain(), hemi)

    vert = pial.vert + fs.surface_ras_shift

    if subject in surf:
        fmri_vals = surf[subject]
    else:
        print(f'Computing surf for {subject}')
        fmri_vals = project_mri_to_surf(
            fmri_file, vert, parameters['plot']['surface']['kernel'])
        surf[subject] = fmri_vals

    colorscale = 'balance'

    traces = [
        go.Scatter3d(
            x=elec['x'],
            y=elec['y'],
            z=elec['z'],
            text=labels,
            mode='markers',
            hoverinfo='text',
            marker=dict(
                size=5,
                color=compare_ieeg['measure'],
                colorscale=colorscale,
                showscale=True,
                cmid=0,
                colorbar=dict(
                    title='electrodes',
                    titleside="top",
                    ticks="outside",
                    ticklabelposition="outside",
                    x=0,
                ),
            ),
        ),
        go.Mesh3d(
            x=vert[:, 0],
            y=vert[:, 1],
            z=vert[:, 2],
            i=pial.tri[:, 0],
            j=pial.tri[:, 1],
            k=pial.tri[:, 2],
            intensity=fmri_vals,
            cmid=0,
            colorscale='Balance',
            hoverinfo='skip',
            flatshading=False,
            colorbar=dict(
                title='fmri',
                titleside="top",
                ticks="outside",
                ticklabelposition="outside",
                x=1,
            ),
            lighting=dict(
                ambient=0.18,
                diffuse=1,
                fresnel=0.1,
                specular=1,
                roughness=0.1,
            ),
            lightposition=dict(
                x=0,
                y=0,
                z=-1,
            ),
        ),
    ]

    fig = go.Figure(
        data=traces,
        layout=go.Layout(scene=dict(
            xaxis=AXIS,
            yaxis=AXIS,
            zaxis=AXIS,
            camera=dict(
                eye=dict(
                    x=right_or_left,
                    y=0,
                    z=0,
                ),
                projection=dict(type='orthographic', ),
            ),
        ), ),
    )

    return to_div(fig)
Exemple #7
0
def test_Electrodes_get_xyz():
    elec = Electrodes(elec_ct.get_filename(BIDS_PATH))

    assert len(elec.get_xyz()) == 28
    assert len(elec.get_xyz(['grid01', ])) == 1
Exemple #8
0
def paper_plot_surf_bold(parameters, subject):

    elec_file = get_path(parameters, 'elec', subject=subject)
    fmri_file = get_path(parameters, 'fmri_nii', subject=subject)

    freesurfer_dir = parameters['paths']['freesurfer_subjects_dir'] / f'sub-{subject}'

    fs = Freesurfer(freesurfer_dir)
    electrodes = Electrodes(elec_file)

    elec = electrodes.electrodes.tsv

    if mean(elec['x']) > 0:
        right_or_left = 1
        hemi = 'rh'
    else:
        right_or_left = -1
        hemi = 'lh'

    fs = Freesurfer(freesurfer_dir)
    pial = getattr(fs.read_brain(), hemi)

    vert = pial.vert + fs.surface_ras_shift
    fmri_vals = project_mri_to_surf(fmri_file, vert, parameters['plot']['surface']['kernel'])

    colorscale = 'balance'

    traces = [
        go.Scatter3d(
            x=elec['x'] + right_or_left,
            y=elec['y'],
            z=elec['z'] + 1,
            mode='markers',
            hoverinfo='text',
            marker=dict(
                size=5,
                color='black',
            ),
        ),
        go.Mesh3d(
            x=vert[:, 0],
            y=vert[:, 1],
            z=vert[:, 2],
            i=pial.tri[:, 0],
            j=pial.tri[:, 1],
            k=pial.tri[:, 2],
            intensity=fmri_vals,
            cmax=4,
            cmin=-4,
            colorscale=colorscale,
            hoverinfo='skip',
            flatshading=False,
            showscale=False,
            lighting=dict(
                ambient=0.18,
                diffuse=1,
                fresnel=0.1,
                specular=1,
                roughness=0.1,
                ),
            lightposition=dict(
                x=0,
                y=0,
                z=-1,
                ),
            ),
        ]

    fig = go.Figure(
        data=traces,
        layout=go.Layout(
            scene=dict(
                xaxis=AXIS,
                yaxis=AXIS,
                zaxis=AXIS,
                camera=dict(
                    eye=dict(
                        x=right_or_left,
                        y=0,
                        z=1,
                    ),
                    projection=dict(
                        type='orthographic',
                    ),
                    ),
                ),
            ),
        )

    return fig
Exemple #9
0
def project_electrodes(elec, freesurfer, analysis_dir):

    elec.acquisition += 'projected'
    bids_root = find_root(elec.filename)
    tsv_electrodes = elec.get_filename(bids_root)

    elec_realigned = {}
    HEMI = {
        'L': 'lh',
        'R': 'rh',
    }

    groups = {x['group'] for x in elec.electrodes.tsv}
    for group in groups:
        print(group)
        anat_dir = analysis_dir / ('sub-' + elec.subject) / 'anat'
        anat_dir.mkdir(exist_ok=True, parents=True)
        labels = [
            x['name'] for x in elec.electrodes.tsv if x['group'] == group
        ]
        hemi = [
            x['hemisphere'] for x in elec.electrodes.tsv if x['group'] == group
        ][0]
        elec_type = [
            x['type'] for x in elec.electrodes.tsv if x['group'] == group
        ][0]
        if not elec_type == 'surface':
            print(f'not realigning {group} because its type is {elec_type}')
            for _elec in elec.electrodes_tsv:
                if _elec['group'] == group:
                    elec_realigned[_elec['label']] = (float(_elec['x']),
                                                      float(_elec['y']),
                                                      float(_elec['z']))

        anat_file = anat_dir / (HEMI[hemi] + '.smooth')
        if not anat_file.exists():
            surf = getattr(freesurfer.read_brain('pial'), HEMI[hemi])
            fill_surface(surf.surf_file, anat_file)

        xyz = array([(float(x['x']), float(x['y']), float(x['z']))
                     for x in elec.electrodes.tsv if x['group'] == group])
        xyz -= freesurfer.surface_ras_shift
        xyz_realigned = snap_elec_to_surf(xyz, anat_file)

        for label, xyz_ in zip(labels, xyz_realigned):
            elec_realigned[label] = xyz_ + freesurfer.surface_ras_shift

    with tsv_electrodes.open('w') as f:
        f.write('name\tgroup\tx\ty\tz\tsize\ttype\tmaterial\themisphere\n')
        for _elec in elec.electrodes.tsv:
            label = _elec['name']
            xyz = "\t".join(f'{x:f}' for x in elec_realigned[label])
            one_chans = [x for x in elec.electrodes.tsv
                         if x['name'] == label][0]
            group = one_chans['group']
            elec_type = one_chans['type']
            size = one_chans['size']
            material = one_chans['material']
            hemisphere = one_chans['hemisphere']
            f.write(
                f'{label}\t{group}\t{xyz}\t{size}\t{elec_type}\t{material}\t{hemisphere}\n'
            )

    elec.coordframe.json[
        'iEEGCoordinateProcessingDescription'] += '; Dijkstra et al.'  # TODO: better description + remove None
    new_json = replace_underscore(tsv_electrodes, 'coordsystem.json')
    with new_json.open('w') as f:
        dump(elec.coordframe.json, f, indent=2)

    return Electrodes(tsv_electrodes)