Ejemplo n.º 1
0
def generate_report(image_in, info_dict={}, ioff=True):
    """Generate a QC report of the segmentation process."""

    report_type = 'reseg'

    # Turn interactive plotting on/off.
    if ioff:
        plt.ioff()
    else:
        plt.ion()

    # Get paths from image if info_dict not provided.
    if not info_dict:
        im = Image(image_in)
        info_dict['paths'] = im.split_path()  # FIXME: out_base
        info_dict['paths']['out_base'] = info_dict['paths']['base']
        im.close()
        info_dict['parameters'] = get_parameters(info_dict, report_type)
        # info_dict['centreslices'] = get_centreslices(info_dict, idss=[])
        info_dict['medians'] = {}

    # Create the axes.
    figsize = (18, 9)
    gridsize = (1, 4)
    f = plt.figure(figsize=figsize, constrained_layout=False)
    gs0 = gridspec.GridSpec(gridsize[0], gridsize[1], figure=f)
    # axs = [gen_orthoplot(f, gs0[j, i]) for j in range(0, 2) for i in range(0, 4)]
    axs = [
        gen_orthoplot(f, gs0[j, i]) for j in range(0, gridsize[0])
        for i in range(0, gridsize[1])
    ]

    # Plot the images and graphs. vmaxs = [15000] + [5000] * 7
    info_dict['plotinfo'] = {'vmax': 10000}
    plot_images(axs, info_dict)

    # Add annotations and save as pdf.
    reseg_id = 'axis{:01d}-seam{:02d}-j{:03d}'.format(info_dict['axis'],
                                                      info_dict['seam'],
                                                      info_dict['j'])
    header = 'mLSR-3D Quality Control'
    figtitle = '{}: {} \n {}'.format(
        header,
        report_type,
        reseg_id,
    )
    figpath = '{}_{}_{}-report.pdf'.format(
        info_dict['paths']['out_base'],
        report_type,
        reseg_id,
    )
    print('writing report to {}'.format(figpath))
    f.suptitle(figtitle, fontsize=14, fontweight='bold')
    add_titles(axs, info_dict)
    f.savefig(figpath)
    plt.close(f)
Ejemplo n.º 2
0
def downsample_channel(image_in,
                       ch,
                       resolution_level=-1,
                       dsfacs=[1, 4, 4, 1, 1],
                       ismask=False,
                       output='',
                       report={}):
    """Downsample an image."""

    ods = 'data' if not ismask else 'mask'

    # return in case no mask provided
    if not image_in:
        return None, report, ''

    if resolution_level != -1 and not ismask:  # we should have an Imaris pyramid
        image_in = '{}/DataSet/ResolutionLevel {}'.format(
            image_in, resolution_level)

    # load data
    im = Image(image_in, permission='r')
    im.load(load_data=False)
    props = im.get_props()
    if len(im.dims) > 4:
        im.slices[im.axlab.index('t')] = slice(0, 1, 1)
        props = im.squeeze_props(props, dim=4)
    if len(im.dims) > 3:
        im.slices[im.axlab.index('c')] = slice(ch, ch + 1, 1)
        props = im.squeeze_props(props, dim=3)
    data = im.slice_dataset()
    im.close()

    # downsample
    dsfac = tuple(dsfacs[:len(data.shape)])
    if not ismask:
        data = downscale_local_mean(data, dsfac).astype('float32')
    else:
        data = block_reduce(data, dsfac, np.max)

    # generate output
    props['axlab'] = 'zyx'  # FIXME: axlab returns as string-list
    props['shape'] = data.shape
    props['elsize'] = [es * ds for es, ds in zip(im.elsize[:3], dsfac)]
    props['slices'] = None
    mo = write_data(data, props, output, ods)

    # report data
    thr = 1000
    meds_mask = data < thr
    report['medians'][ods] = get_zyx_medians(data, meds_mask)

    c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'}
    report['centreslices'][ods] = c_slcs

    return mo, report, meds_mask
Ejemplo n.º 3
0
def extract_resolution_level(image_in, resolution_level, output='', report={}):
    """Extract data from a 5D Imaris image pyramid and create 4D image."""

    if resolution_level != -1:
        image_in = '{}/DataSet/ResolutionLevel {}'.format(image_in, resolution_level)

    mo = Image(image_in, permission='r')
    mo.load(load_data=False)

    report['parameters']['n_channels'] = mo.dims[mo.axlab.index('c')]

    return mo, report
Ejemplo n.º 4
0
def get_centreslice(image_in, ids, dim='z', ch=0):
    """Return an image's centreslice for a dimension."""

    if isinstance(image_in, Image):
        im = image_in
    else:
        im = Image('{}/{}'.format(image_in, ids))
        try:
            im.load(load_data=False)
        except KeyError:
            print('dataset {} not found'.format(ids))
            return None

    if len(im.dims) > 3:
        ch_idx = im.axlab.index('c')
        im.slices[ch_idx] = slice(ch, ch + 1, 1)

    dim_idx = im.axlab.index(dim)
    cslc = int(im.dims[dim_idx] / 2)

    slcs = [slc for slc in im.slices]
    im.slices[dim_idx] = slice(cslc, cslc + 1, 1)
    data = im.slice_dataset()
    im.slices = slcs

    return data
Ejemplo n.º 5
0
def add_features(df, image_in='', origin=[0, 0, 0], dsfacs=[1, 16, 16]):

    if 'centroid-0' in df.columns:

        cens = ['centroid-{}'.format(i) for i in [0, 1, 2]]
        coms = ['com_{}'.format(d) for d in 'zyx']

        df[coms] = df[cens] + origin

        if image_in:

            dt_im = Image(image_in, permission='r')
            dt_im.load(load_data=False)
            data = dt_im.slice_dataset()
            dt_im.close()

            ds_centroid = np.array(df[coms] / dsfacs, dtype='int')
            ds_centroid = [data[p[0], p[1], p[2]] for p in ds_centroid]
            df['dist_to_edge'] = np.array(ds_centroid)

    if 'inertia_tensor_eigvals-0' in df.columns:
        ites = ['inertia_tensor_eigvals-{}'.format(i) for i in [0, 1, 2]]
        eigvals = np.clip(np.array(df[ites]), 0, np.inf)
        df['fractional_anisotropy'] = fractional_anisotropy(eigvals)
        df['major_axis_length'] = get_ellips_axis_lengths(eigvals[:, 0])
        df['minor_axis_length'] = get_ellips_axis_lengths(eigvals[:, -1])

    # TODO: range, variance, ...

    return df
Ejemplo n.º 6
0
def generate_report(image_in, info_dict={}, ioff=True):
    """Generate a QC report of the mask creation process."""

    report_type = 'mask'

    # Turn interactive plotting on/off.
    if ioff:
        plt.ioff()
    else:
        plt.ion()

    # Get paths from image if info_dict not provided.
    if not info_dict:
        im = Image(image_in)
        info_dict['paths'] = im.split_path()
        im.close()
        info_dict['parameters'] = get_parameters(info_dict, report_type)
        info_dict['centreslices'] = get_centreslices(info_dict)
        # info_dict['medians'] = get_medians(info_dict)

    # Create the axes.
    figsize = (18, 9)
    gridsize = (1, 4)
    f = plt.figure(figsize=figsize, constrained_layout=False)
    gs0 = gridspec.GridSpec(gridsize[0], gridsize[1], figure=f)
    axs = [gen_orthoplot(f, gs0[0, i]) for i in range(0, 4)]

    # Plot the images and graphs.
    info_dict['plotinfo'] = {'vmax': 10000}
    plot_images(axs, info_dict)

    # Add annotations and save as pdf.
    header = 'mLSR-3D Quality Control'
    figtitle = '{}: {} \n {}'.format(
        header,
        report_type,
        info_dict['paths']['fname']
        )
    figpath = '{}_{}-report.pdf'.format(
        info_dict['paths']['base'],
        report_type
        )
    f.suptitle(figtitle, fontsize=14, fontweight='bold')
    add_titles(axs, info_dict)
    f.savefig(figpath)
Ejemplo n.º 7
0
def write_output(outpath, out, props):

    props['dtype'] = out.dtype
    mo = Image(outpath, **props)
    mo.create()
    mo.write(out)

    return mo
Ejemplo n.º 8
0
def write_output(outpath, out, props, imtype='Label'):
    """Write data to an image on disk."""

    props['dtype'] = out.dtype
    if imtype == 'Label':
        mo = LabelImage(outpath, **props)
    elif imtype == 'Mask':
        mo = MaskImage(outpath, **props)
    else:
        mo = Image(outpath, **props)
    mo.create()
    mo.write(out)

    return mo
Ejemplo n.º 9
0
def read_image(im_info, ids='segm/labels_memb_del', imtype='Label'):
    """"Read a h5 dataset as Image object."""

    fname = '{}_{}'.format(im_info['base'], im_info['postfix'])
    fstem = os.path.join(im_info['datadir'], fname)
    if imtype == 'Label':
        im = LabelImage('{}.h5/{}'.format(fstem, ids))
    elif imtype == 'Mask':
        im = MaskImage('{}.h5/{}'.format(fstem, ids))
    else:
        im = Image('{}.h5/{}'.format(fstem, ids))
    im.load(load_data=False)
    if imtype == 'Label':
        im.set_maxlabel()

    return im
Ejemplo n.º 10
0
def extract_mean(im, dim='c', keep_dtype=True, output='', report={}):
    """Calculate mean over channels."""

    ods = 'mean'

    im.load(load_data=False)
    props = im.get_props()
    if len(im.dims) > 4:
        props = im.squeeze_props(props, dim=4)
    if len(im.dims) > 3:
        props = im.squeeze_props(props, dim=3)

    mo = Image(output.format(ods), **props)
    mo.create()

    zdim = im.axlab.index('z')
    if im.chunks is not None:
        nslcs = im.chunks[zdim]
    else:
        nslsc = 8
    slc_thrs = []
    for zstart in range(0, im.dims[zdim], nslcs):
        zstop = min(im.dims[zdim], zstart + nslcs)
        im.slices[zdim] = mo.slices[zdim] = slice(zstart, zstop, None)
        data_mean = np.mean(im.slice_dataset(), axis=im.axlab.index(dim))
        if keep_dtype:
            data_mean = data_mean.astype(im.dtype)
        mo.write(data_mean)
        slc_thrs += list(np.median(np.reshape(data_mean, [data_mean.shape[0], -1]), axis=1))

    mo.slices = None
    mo.set_slices()

    im.close()

    c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'}
    report['centreslices'][ods] = c_slcs

    return mo, report, slc_thrs
Ejemplo n.º 11
0
def write_data(data, props, out_template='', ods=''):
    """Create an Image object and optionally write to file."""

    outputpath = ''
    if out_template:
        outputpath = out_template.format(ods)

    props['dtype'] = data.dtype
    mo = Image(outputpath, **props)
    mo.create()
    mo.write(data)
    # mo.close()

    return mo
Ejemplo n.º 12
0
def get_maxlabels_from_attribute(filelist, ids, maxlabelfile):

    maxlabels = []

    for datafile in filelist:
        image_in = '{}/{}'.format(datafile, ids)
        im = Image(image_in, permission='r')
        im.load(load_data=False)
        maxlabels.append(im.ds.attrs['maxlabel'])
        im.close()

    if maxlabelfile:
        np.savetxt(maxlabelfile, maxlabels, fmt='%d')

    return maxlabels
Ejemplo n.º 13
0
def get_info_dict(image_in, info_dict={}, report_type='bfc', channel=0):

    im = Image(image_in)
    im.load(load_data=False)
    info_dict['elsize'] = {dim: im.elsize[i] for i, dim in enumerate(im.axlab)}
    info_dict['paths'] = im.split_path()  # FIXME: out_base
    info_dict['paths']['out_base'] = info_dict['paths']['base']
    im.close()

    ppath = '{}.pickle'.format(info_dict['paths']['base'])
    with open(ppath, 'rb') as f:
        info_dict['parameters'] = pickle.load(f)
    info_dict['centreslices'] = get_centreslices(info_dict)

    # info_dict['medians'] = get_medians(info_dict)
    info_dict['medians'], info_dict['means'], info_dict['stds'], info_dict[
        'n_samples'] = get_means_and_stds(info_dict, ch=channel, thr=1000)

    return info_dict
Ejemplo n.º 14
0
def get_data(h5_path, ids, ch=0, dim=''):

    im = Image('{}/{}'.format(h5_path, ids))
    im.load(load_data=False)

    if dim:
        dim_idx = im.axlab.index(dim)
        cslc = int(im.dims[dim_idx] / 2)
        im.slices[dim_idx] = slice(cslc, cslc + 1, 1)

    if len(im.dims) > 3:
        im.slices[im.axlab.index('c')] = slice(ch, ch + 1, 1)

    data = im.slice_dataset()

    return data
Ejemplo n.º 15
0
def get_centreslices(info_dict, idss=[], ch=0):
    """Get the centreslices for all dims and steps."""

    h5_path = info_dict['paths']['file']
    image_in = h5_path + info_dict['paths']['int']
    im = Image(image_in)
    im.load(load_data=False)
    if not idss:
        idss = [k for k in im.file.keys()]
    im.close()

    centreslices = {
        ids: {dim: get_centreslice(h5_path, ids, dim, ch)
              for dim in 'zyx'}
        for ids in idss
    }

    return centreslices
Ejemplo n.º 16
0
def write(out, outstem, postfix, ref_im, imtype='Image'):
    """Write an image to disk."""

    outstem = outstem or gen_outpath(ref_im, '')
    outpath = '{}{}'.format(outstem, postfix)

    props = ref_im.get_props()
    props['dtype'] = out.dtype

    if imtype == 'Label':
        mo = LabelImage(outpath, **props)
    elif imtype == 'Mask':
        mo = MaskImage(outpath, **props)
    else:
        mo = Image(outpath, **props)

    mo.create()
    mo.write(out)

    if imtype == 'Label':
        mo.set_maxlabel()
        mo.ds.attrs.create('maxlabel', mo.maxlabel, dtype='uint32')

    return mo
Ejemplo n.º 17
0
def get_paths(image_in,
              resolution_level=-1,
              channel=0,
              outputstem='',
              step='',
              save_steps=False):
    """Get the parameters for the preprocessing step."""

    # get paths from input file
    if resolution_level != -1:  # we should have an Imaris pyramid
        image_in = '{}/DataSet/ResolutionLevel {}'.format(
            image_in, resolution_level)
    im = Image(image_in, permission='r')
    im.load(load_data=False)
    paths = im.split_path()
    im.close()

    # define output basename
    paths['out_base'] = outputstem

    # define h5 output template
    paths['out_h5'] = '{}.h5/{}'.format(paths['out_base'], '{}')

    # define output for main results and intermediate steps
    if not outputstem:
        paths['main'] = paths['steps'] = ''
    else:
        ### FIXME ????????????? what is this?
        if save_steps:
            paths['main'] = paths['steps'] = paths['out_h5']
        else:
            paths['main'] = paths['out_h5']
            paths['steps'] = paths['out_h5']

    # define output for parameters
    paths['params'] = '{}.pickle'.format(paths['out_base'], step)

    return paths
Ejemplo n.º 18
0
def biasfield_correction(
    image_in,
    parameter_file='',
    outputdir='',
    channels=[],
    mask_in='',
    resolution_level=-1,
    downsample_factors=[1, 1, 1, 1, 1],
    n_iterations=50,
    n_fitlevels=4,
    n_bspline_cps=[5, 5, 5],
):
    """Perform N4 bias field correction."""

    params = get_params(locals(), parameter_file, 'biasfield_correction')

    if not params['channels']:
        im = Image(image_in, permission='r')
        im.load()
        n_channels = im.dims[im.axlab.index('c')]
        params['channels'] = list(range(n_channels))
        im.close()

    n_workers = get_n_workers(len(params['channels']), params)

    arglist = [(
        image_in,
        ch,
        params['mask_in'],
        params['resolution_level'],
        params['downsample_factors'],
        params['n_iterations'],
        params['n_fitlevels'],
        params['n_bspline_cps'],
        outputdir,
    ) for ch in params['channels']]

    with multiprocessing.Pool(processes=n_workers) as pool:
        pool.starmap(estimate_biasfield, arglist)
Ejemplo n.º 19
0
    def apply_field(image_in, bias_in, outputpath):

        im = Image(image_in, permission='r+')
        im.load(load_data=True)
        bf = Image(bias_in, permission='r+')
        bf.load(load_data=True)

        corr = divide_bias_field(im, bf, outputpath)

        im.close()
        bf.close()
        corr.close()
Ejemplo n.º 20
0
def csv_to_im(
    image_in,
    csv_path,
    labelkey='label',
    key='dapi',
    name='',
    maxlabel=0,
    normalize=False,
    scale_uint16=False,
    replace_nan=False,
    channel=-1,
    outpath='',
):
    """Write segment backprojection."""

    if isinstance(image_in, Image):
        labels = image_in
    else:
        labels = LabelImage(image_in)
        labels.load(load_data=False)

    if not maxlabel:
        labels.set_maxlabel()
        maxlabel = labels.maxlabel

    if csv_path.endswith('.csv'):
        df = pd.read_csv(csv_path)
        df = df.astype({labelkey: int})
    elif csv_path.endswith('.h5ad'):
        import scanpy as sc
        adata = sc.read(csv_path)
        if not csv_path.endswith('_nofilter.h5ad'):
            adata.X = adata.raw.X
        df = adata.obs[labelkey].astype(int)
        df = pd.concat([df, adata[:, key].to_df()], axis=1)

    # for key in keys:  # TODO
    fw = np.zeros(maxlabel + 1, dtype='float')
    for index, row in df.iterrows():
        fw[int(row[labelkey])] = row[key]

    if replace_nan:
        fw = np.nan_to_num(fw)
    if normalize:

        def normalize_data(data):
            """Normalize data between 0 and 1."""
            data = data.astype('float64')
            datamin = np.amin(data)
            datamax = np.amax(data)
            data -= datamin
            data *= 1 / (datamax - datamin)
            return data, [datamin, datamax]

        fw_n, fw_minmax = normalize_data(fw)
        fw_n *= 65535
        fw = fw_n
    elif scale_uint16:  # for e.g. pseudotime / FA / etc / any [0, 1] vars
        fw *= 65535

    out = labels.forward_map(list(fw))

    if outpath.endswith('.ims'):
        mo = Image(outpath, permission='r+')
        mo.load(load_data=False)
        if channel >= 0 and channel < mo.dims[3]:
            ch = channel
        else:
            mo.create()
            ch = mo.dims[3] - 1
        mo.slices[3] = slice(ch, ch + 1, 1)
        mo.write(out.astype(mo.dtype))  # FIXME: >65535 wraps around
        cpath = 'DataSetInfo/Channel {}'.format(ch)
        name = name or key
        mo.file[cpath].attrs['Name'] = np.array([c for c in name], dtype='|S1')
        mo.close()
    elif outpath.endswith('.nii.gz'):
        props = labels.get_props()
        if not labels.path.endswith('.nii.gz'):
            props = transpose_props(props, outlayout='xyz')
            out = out.transpose()
        mo = write_output(outpath, out, props)
    else:
        outpath = outpath or gen_outpath(labels, key)
        mo = write_output(outpath, out, labels.get_props())

    return mo
Ejemplo n.º 21
0
def generate_report(image_in, info_dict={}, ioff=True):
    """Generate a QC report of the segmentation process."""

    report_type = 'seg'

    # Turn interactive plotting on/off.
    if ioff:
        plt.ioff()
    else:
        plt.ion()

    # Get paths from image if info_dict not provided.
    if not info_dict:
        im = Image(image_in)
        info_dict['paths'] = im.split_path()  # FIXME: out_base
        info_dict['paths']['out_base'] = info_dict['paths']['base']
        im.close()
        info_dict['parameters'] = load_parameters(
            info_dict['paths']['out_base'])
        info_dict['centreslices'] = get_centreslices(
            info_dict,
            idss=[
                'mean_mask',
                'memb/planarity_mask',
                'memb/mean',
                'memb/mean_smooth',
                'chan/ch00',
                'nucl/dapi_mask',
                'nucl/dapi_preprocess',
                'segm/labels_edt',
                'segm/labels_memb',
                'segm/labels_memb_del',
                'segm/seeds_edt',
                'segm/seeds_mask',
                'segm/seeds_peaks_dil',
            ])
        info_dict['medians'] = {}

    # Create the axes.
    figsize = (18, 9)
    gridsize = (2, 4)
    f = plt.figure(figsize=figsize, constrained_layout=False)
    gs0 = gridspec.GridSpec(gridsize[0], gridsize[1], figure=f)
    axs = [
        gen_orthoplot(f, gs0[j, i]) for j in range(0, 2) for i in range(0, 4)
    ]

    # Plot the images and graphs. vmaxs = [15000] + [5000] * 7
    info_dict['plotinfo'] = {'vmax': 10000}
    plot_images(axs, info_dict)

    # Add annotations and save as pdf.
    header = 'mLSR-3D Quality Control'
    figtitle = '{}: {} \n {}'.format(header, report_type,
                                     info_dict['paths']['fname'])
    figpath = '{}_{}-report.pdf'.format(info_dict['paths']['out_base'],
                                        report_type)
    f.suptitle(figtitle, fontsize=14, fontweight='bold')
    add_titles(axs, info_dict)
    f.savefig(figpath)

    info_dict.clear()
Ejemplo n.º 22
0
def cell_segmentation(
    plan_path,
    memb_path,
    dapi_path,
    mean_path,
    dapi_shift_planes=0,
    nucl_opening_footprint=[3, 7, 7],
    dapi_filter='median',
    dapi_sigma=1,
    dapi_dog_sigma1=2,
    dapi_dog_sigma2=4,
    dapi_thr=0,
    sauvola_window_size=[19, 75, 75],
    sauvola_k=0.2,
    dapi_absmin=500,
    dapi_erodisk=0,
    dist_max=5,
    peaks_size=[11, 19, 19],
    peaks_thr=1.0,
    peaks_dil_footprint=[3, 7, 7],
    compactness=0.80,
    memb_filter='median',
    memb_sigma=3,
    planarity_thr=0.0005,
    dset_mask_filter='gaussian',
    dset_mask_sigma=50,
    dset_mask_thr=1000,
    steps=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    outputstem='',
    save_steps=False,
):

    step = 'segment'
    paths = get_paths(plan_path, -1, 0, outputstem, step, save_steps)
    report = {
        'parameters': locals(),
        'paths': paths,
        'medians': {},
        'centreslices': {}
    }

    # load images
    im_dapi = Image(dapi_path)
    im_dapi.load()
    nucl_props = im_dapi.get_props()

    im_memb = MaskImage(memb_path)
    im_memb.load()
    memb_props = im_memb.get_props()

    im_plan = MaskImage(plan_path)
    im_plan.load()

    # im_dset_mask = Image(dset_mask_path, permission='r')
    # im_dset_mask.load(load_data=False)
    im_mean = Image(mean_path)
    im_mean.load()

    # preprocess dapi channel
    # .h5/nucl/dapi<_shifted><_opened><_preprocess>
    stage = 'nucleus channel'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/nucl/dapi')
    if 0 not in steps:
        op = 'reading'
        im_dapi_pp = get_image('{}{}'.format(outstem, '_preprocess'))
    else:
        op = 'processing'
        im_dapi_pp = preprocess_nucl(
            im_dapi,
            dapi_shift_planes,
            dapi_filter,
            dapi_sigma,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # create a nuclear mask from the dapi channel
    # .h5/nucl/dapi<_mask_thr><_sauvola><_mask><_mask_ero>
    stage = 'nucleus mask'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/nucl/dapi')
    if 1 not in steps:
        op = 'reading'
        im_dapi_mask = get_image('{}{}'.format(outstem, '_mask_ero'))
    else:
        op = 'processing'
        im_dapi_mask = create_nuclear_mask(
            im_dapi_pp,
            dapi_thr,
            sauvola_window_size,
            sauvola_k,
            dapi_absmin,
            dapi_erodisk,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # create a membrane mask from the membrane mean
    # .h5/memb/planarity<_mask>
    stage = 'membrane mask'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/memb/planarity')
    if 2 not in steps:
        op = 'reading'
        im_memb_mask = get_image('{}{}'.format(outstem, '_mask'))
    else:
        op = 'processing'
        im_memb_mask = create_membrane_mask(
            im_plan,
            planarity_thr,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # combine nuclear and membrane mask
    # .h5/segm/seeds<_mask>
    stage = 'mask combination'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/segm/seeds')
    if 3 not in steps:
        op = 'reading'
        im_nucl_mask = get_image('{}{}'.format(outstem, '_mask'))
    else:
        op = 'processing'
        im_nucl_mask = combine_nucl_and_memb_masks(
            im_memb_mask,
            im_dapi_mask,
            nucl_opening_footprint,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # find seeds for watershed
    stage = 'nucleus detection'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/segm/seeds')
    if 4 not in steps:
        op = 'reading'
        im_dt = get_image('{}{}'.format(outstem, '_edt'))
        im_peaks = get_image('{}{}'.format(outstem, '_peaks'))
    # .h5/segm/seeds<_edt><_mask_distmax><_peaks><_peaks_dil>
    else:
        op = 'processing'
        im_dt, im_peaks = define_seeds(
            im_nucl_mask,
            im_memb_mask,
            im_dapi_pp,
            dapi_dog_sigma1,
            dapi_dog_sigma2,
            dist_max,
            peaks_size,
            peaks_thr,
            peaks_dil_footprint,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # preprocess membrane mean channel
    # .h5/memb/preprocess<_smooth>
    stage = 'membrane channel'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/memb/mean')
    if 5 not in steps:
        op = 'reading'
        im_memb_pp = get_image('{}{}'.format(outstem, '_smooth'))
    else:
        op = 'processing'
        im_memb_pp = preprocess_memb(
            im_memb,
            memb_filter,
            memb_sigma,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # perform watershed from the peaks to fill the nuclei
    # .h5/segm/labels<_edt><_memb>
    stage = 'watershed'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/segm/labels')
    if 6 not in steps:
        op = 'reading'
        im_ws = get_image('{}{}'.format(outstem, '_memb'), imtype='Label')
    else:
        op = 'processing'
        im_ws = perform_watershed(
            im_peaks,
            im_memb_pp,
            im_dt,
            peaks_thr,
            memb_sigma,
            memb_filter,
            compactness,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # generate a dataset mask from the mean of all channels
    # .h5/mean<_smooth><_mask>
    stage = 'dataset mask'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/mean')
    if 7 not in steps:
        op = 'reading'
        im_dset_mask = get_image('{}{}'.format(outstem, '_mask'),
                                 imtype='Mask')
    else:
        op = 'processing'
        im_dset_mask = create_dataset_mask(
            im_mean,
            filter=dset_mask_filter,
            sigma=dset_mask_sigma,
            threshold=dset_mask_thr,
            outstem=outstem,
            save_steps=save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # filter the segments with the dataset mask
    # .h5/segm/labels<_memb_del>
    # .h5/mask
    stage = 'segment filter'
    t = time.time()
    outstem = '{}.h5{}'.format(outputstem, '/segm/labels')
    if 8 not in steps:
        im_ws_pp = get_image('{}{}'.format(outstem, '_memb_del'),
                             imtype='Label')
    else:
        op = 'processing'
        im_ws_pp = segmentation_postprocessing(
            im_dset_mask,
            im_ws,
            outstem,
            save_steps,
        )
    elapsed = time.time() - t
    print('{} ({}) took {:1f} s'.format(stage, op, elapsed))

    # write report
    generate_report('{}.h5/{}'.format(outputstem, 'mean_mask'))

    return im_ws_pp
Ejemplo n.º 23
0
def stack_channels(images_in, outputpath=''):

    channels = []
    for image_in in images_in:
        im = Image(image_in, permission='r')
        im.load(load_data=True)
        channels.append(im.ds[:])
    data = np.stack(channels, axis=3)

    mo = Image(outputpath)
    mo.elsize = list(im.elsize) + [1]
    mo.axlab = im.axlab + 'c'
    mo.dims = data.shape
    mo.chunks = list(im.chunks) + [1]
    mo.dtype = im.dtype
    mo.set_slices()
    if outputpath:
        mo.create()
        mo.write(data)
        mo.close()

    return mo
Ejemplo n.º 24
0
def export_regionprops(
    seg_paths,
    seg_names=['full', 'memb', 'nucl'],
    data_paths=[],
    data_names=[],
    aux_data_path=[],
    downsample_factors=[1, 1, 1],
    outputstem='',
    blocksize=[],
    blockmargin=[],
    blockrange=[],
    channels=[],
    filter_borderlabels=False,
    min_labelsize=0,
    split_features=False,
    fset_morph=['label'],
    fset_intens=['mean_intensity'],
    fset_addit=['com_z', 'com_y', 'com_x'],
):

    # load the segments: ['full'] or ['full', 'memb', 'nucl']
    label_ims = {}
    pfs = seg_names[:len(seg_paths)]
    for pf, seg_path in zip(pfs, seg_paths):
        im = LabelImage(seg_path, permission='r')
        im.load(load_data=False)
        label_ims[pf] = im
    comps = label_ims['full'].split_path()

    # prepare parallel processing
    mpi_label = wmeMPI(usempi=False)
    blocksize = blocksize or label_ims['full'].dims
    mpi_label.set_blocks(label_ims['full'], blocksize, blockmargin, blockrange)
    mpi_label.scatter_series()

    # load the data
    data_ims = {}
    mpi_data = wmeMPI(usempi=False)
    for i, data_path in enumerate(data_paths):
        pf = 'im{:02d}'.format(i)
        data = Image(data_path, permission='r')
        data.load(load_data=False)
        ch_idx = data.axlab.index('c')
        # FIXME channels for multiple data_paths
        chs = channels or [ch for ch in range(data.dims[ch_idx])]
        names = [data_names.pop(0) for _ in range(len(chs))]
        data_ims[pf] = {'im': data, 'ch': chs, 'names': names}
        """ TODO
        try:
            mpi_data.blocks = [
                {'id': split_filename(comps['file'])[0]['postfix'],
                 'slices': dset_name2slices(comps['file'], axlab=data.axlab, shape=data.dims),
                 'path': '',},
                ]
        except:
        """
    mpi_data.set_blocks(data, blocksize, blockmargin, blockrange)

    border_labelset = set([])
    #    if filter_borderlabels:
    #        outstem = outputstem or label_ims['full'].split_path()['base']
    #        outstem += '_dataset'
    #        border_labelset |= filter_borders(label_ims['full'], outstem)

    dfs = []
    for i in mpi_label.series:
        print('processing block {:03d} with id: {}'.format(
            i, mpi_label.blocks[i]['id']))
        dfs.append(
            process_block(
                mpi_label.blocks[i],
                mpi_data.blocks[i],
                label_ims,
                split_features,
                data_ims,
                min_labelsize,
                channels,
                filter_borderlabels,
                fset_morph,
                fset_intens,
                fset_addit,
                border_labelset,
                outputstem,
                aux_data_path,
                downsample_factors,
            ))

    return dfs
Ejemplo n.º 25
0
def process_block(image_in, ndim, blockreduce, func, blockoffset, blocksize,
                  margin, fullsize, mo, is_labelimage, relabel, neighbourmerge,
                  save_fwmap, maxlabel, mpi):
    """Write a block of data into a hdf5 file."""

    # open data for reading
    im = Image(image_in, permission='r')
    im.load(mpi.comm, load_data=False)

    # get the indices into the input and output datasets
    # TODO: get indices from attributes
    # TODO: get from mpi.get_blocks
    set_slices_in_and_out(im, mo, blocksize, margin, fullsize)

    # simply copy the data from input to output
    """NOTE:
    it is assumed that the inputs are not 4D labelimages
    """
    if ndim == 4:
        mo.write(im.slice_dataset())
        im.close()
        return
    if ((not is_labelimage)
            or ((not relabel) and (not neighbourmerge) and (not blockreduce))):
        data = im.slice_dataset()
        #datatype = 'uint16'
        #from skimage.util.dtype import convert
        #data = convert(data, np.dtype(datatype), force_copy=False)
        mo.write(data)
        im.close()
        return

    # forward map to relabel the blocks in the output
    if relabel:
        # FIXME: make sure to get all data in the block
        fw, maxlabel = relabel_block(im.ds[:], maxlabel, mpi)
        if save_fwmap:
            comps = im.split_path()
            fpath = '{}_{}.npy'.format(comps['base'], comps['int'][1:])
            np.save(fpath, fw)
        if (not neighbourmerge) and (not blockreduce):
            data = im.slice_dataset()
            mo.write(fw[data])
            im.close()
            return
    else:
        ulabels = np.unique(im.ds[:])
        fw = [l for l in range(0, np.amax(ulabels) + 1)]
        fw = np.array(fw)

    # blockwise reduction of input datasets
    if blockreduce is not None:
        pass
    else:
        data = im.slice_dataset()

    # merge overlapping labels
    fw = merge_overlap(fw, im, mo, data, margin)
    mo.write(fw[data])
    im.close()
Ejemplo n.º 26
0
def mergeblocks(
    images_in,
    dataslices=None,
    blocksize=[],
    blockmargin=[],
    blockrange=[],
    blockoffset=[0, 0, 0],
    fullsize=[],
    is_labelimage=False,
    relabel=False,
    neighbourmerge=False,
    save_fwmap=False,
    blockreduce=[],
    func='np.amax',
    datatype='',
    usempi=False,
    outputpath='',
    save_steps=False,
    protective=False,
):
    """Merge blocks of data into a single hdf5 file."""

    if blockrange:
        images_in = images_in[blockrange[0]:blockrange[1]]

    mpi = wmeMPI(usempi)

    im = Image(images_in[0], permission='r')
    im.load(mpi.comm, load_data=False)
    props = im.get_props(protective=protective, squeeze=True)
    ndim = im.get_ndim()

    props['dtype'] = datatype or props['dtype']
    props['chunks'] = props['chunks'] or None

    # get the size of the outputfile
    # TODO: option to derive fullsize from dset_names?
    if blockreduce:
        datasize = np.subtract(fullsize, blockoffset)
        outsize = [
            int(np.ceil(d / np.float(b)))
            for d, b in zip(datasize, blockreduce)
        ]
        props['elsize'] = [e * b for e, b in zip(im.elsize, blockreduce)]
    else:  # FIXME: 'zyx(c)' stack assumed
        outsize = np.subtract(fullsize, blockoffset)

    if ndim == 4:
        outsize = list(outsize) + [im.ds.shape[3]]  # TODO: flexible insert

    if outputpath.endswith('.ims'):
        mo = LabelImage(outputpath)
        mo.create(comm=mpi.comm)
    else:
        props['shape'] = outsize
        mo = LabelImage(outputpath, **props)
        mo.create(comm=mpi.comm)

    mpi.blocks = [{'path': image_in} for image_in in images_in]
    mpi.nblocks = len(images_in)
    mpi.scatter_series()

    # merge the datasets
    maxlabel = 0
    for i in mpi.series:

        block = mpi.blocks[i]
        # try:
        maxlabel = process_block(block['path'], ndim, blockreduce, func,
                                 blockoffset, blocksize, blockmargin, fullsize,
                                 mo, is_labelimage, relabel, neighbourmerge,
                                 save_fwmap, maxlabel, mpi)
        print('processed block {:03d}: {}'.format(i, block['path']))
        # except Exception as e:
        #     print('failed block {:03d}: {}'.format(i, block['path']))
        #     print(e)

    im.close()
    mo.close()

    return mo
Ejemplo n.º 27
0
def apply_bias_field_full(image_in,
                          bias_in,
                          dsfacs=[1, 64, 64, 1],
                          in_place=False,
                          write_to_single_file=False,
                          blocksize_xy=1280,
                          outputpath='',
                          channel=None):
    """single-core in ~200 blocks"""

    perm = 'r+' if in_place else 'r'
    im = Image(image_in, permission=perm)
    im.load(load_data=False)

    bf = Image(bias_in, permission='r')
    bf.load(load_data=False)

    if channel is not None:
        im.slices[3] = slice(channel, channel + 1)
    if write_to_single_file:  # assuming single-channel copied file here
        mo = Image(outputpath)
        mo.load()
        mo.slices[3] = slice(0, 1, 1)

    mpi = wmeMPI(usempi=False)
    mpi_nm = wmeMPI(usempi=False)
    if blocksize_xy:
        blocksize = [im.dims[0], blocksize_xy, blocksize_xy, 1, 1]
        blockmargin = [0, im.chunks[1], im.chunks[2], 0, 0]
    else:
        blocksize = im.dims[:3] + [1, 1]
        blockmargin = [0] * len(im.dims)
    mpi.set_blocks(im, blocksize, blockmargin)
    mpi_nm.set_blocks(im, blocksize)
    mpi.scatter_series()

    for i in mpi.series:
        print(i)
        block = mpi.blocks[i]
        data_shape = list(im.slices2shape(block['slices']))
        block_nm = mpi_nm.blocks[i]
        it = zip(block['slices'], block_nm['slices'], blocksize, data_shape)
        data_shape = list(im.slices2shape(block_nm['slices']))
        data_slices = []
        for b_slc, n_slc, bs, ds in it:
            m_start = n_slc.start - b_slc.start
            m_stop = m_start + bs
            m_stop = min(m_stop, ds)
            data_slices.append(slice(m_start, m_stop, None))
        data_slices[3] = block['slices'][3]
        data_shape = list(im.slices2shape(data_slices))

        # get the fullres image block
        im.slices = block['slices']
        data = im.slice_dataset().astype('float')

        # get the upsampled bias field
        bias = get_bias_field_block(bf, im.slices, data.shape)
        data /= bias
        data = np.nan_to_num(data, copy=False)

        if in_place:
            im.slices = block_nm['slices']
            data = data[tuple(data_slices[:3])].astype(im.dtype)
            im.write(data)
        elif write_to_single_file:
            mo.slices = block_nm['slices']
            mo.slices[3] = slice(0, 1, 1)
            data = data[tuple(data_slices[:3])].astype(mo.dtype)
            mo.write(data)
        else:
            props = im.get_props()
            if len(im.dims) > 4:
                props = im.squeeze_props(props, dim=4)
            if len(im.dims) > 3:
                props = im.squeeze_props(props, dim=3)
            props['axlab'] = 'zyx'  # FIXME: axlab return as string-list
            props['shape'] = bias.shape
            props['slices'] = None
            props['dtype'] = bias.dtype
            mo = Image(block['path'], **props)  # FIXME: needs channel
            mo.create(comm=mpi.comm)
            mo.slices = None
            mo.set_slices()
            mo.write(data=bias)
            mo.close()

    im.close()
    bf.close()