Пример #1
0
def particles_xyz_to_np_array(motl_em_file, scaling_factor=1):
    """
    Extracts coordinates of all particles from a motive list EM file and returns
    them in numpy array format.

    Optionally, scales the coordinates by multiplying with a given scaling
    factor.

    Args:
        motl_em_file (str): TOM motive list EM file holding the particle
            coordinates in rows 8-10
        scaling_factor (int, optional): scaling factor by which the coordinates
            are multiplied; if 1 (default), no scaling is performed

    Returns:
        a 2D array containing the particle coordinates in format
        [[x1, y1, z1], [x2, y2, z2], ...] (numpy.ndarray)
    """
    motl = io.load_tomo(motl_em_file)
    particles_xyz = []
    for col in xrange(motl.shape[1]):
        x = scaling_factor * motl[7, col, 0]
        y = scaling_factor * motl[8, col, 0]
        z = scaling_factor * motl[9, col, 0]
        particles_xyz.append([x, y, z])
    particles_xyz = np.array(particles_xyz)
    return particles_xyz
Пример #2
0
def read_in_mask(mask_file, verbose=False):
    """
    A wrapper for reading in a membrane segmentation or ribosome centers mask
    (binary tomographic data).

    Args:
        mask_file (str): a mask file in EM, MRC or VTI format
        verbose (boolean, optional): if True (default False), some extra
            information will be printed out

    Returns:
        the read in mask (numpy.ndarray)
    """
    print '\nReading in the mask %s' % mask_file
    mask = io.load_tomo(mask_file)
    if verbose:
        print 'Shape and data type:'
        print mask.shape
        print mask.dtype
    return mask
Пример #3
0
def close_holes(infile, cube_size, iterations, outfile):
    """
    Closes small holes in a binary volume by using a binary closing operation.

    Args:
        infile (str): input 'MRC' file with a binary volume
        cube_size (str): size of the cube used for the binary closing operation
            (dilation followed by erosion)
        iterations (int): number of closing iterations
        outfile (str): output 'MRC' file with the closed volume

    Returns:
        None
    """
    tomo = io.load_tomo(infile)
    data_type = tomo.dtype  # dtype('uint8')
    tomo_closed = ndimage.binary_closing(
        tomo,
        structure=np.ones((cube_size, cube_size, cube_size)),
        iterations=iterations).astype(data_type)
    io.save_numpy(tomo_closed, outfile)
Пример #4
0
def split_segmentation(infile, lbl=1, close=True, close_cube_size=5,
                       close_iter=1, min_region_size=100):
    """
    Splits the segmentation in connected regions with at least the given size
    (number of voxels).

    Args:
        infile (str): the segmentation input file in one of the formats: '.mrc'
            '.em' or '.vti'.
        lbl (int, optional) the label to be considered, 0 will be ignored,
            default 1
        close (boolean, optional): if True (default), closes small holes in the
            segmentation first
        close_cube_size (int, optional): if close is True, gives the size of the
            cube structuring element used for closing, default 5
        close_iter (int, optional): if close is True, gives the number of
            iterations the closing should be repeated, default 1
        min_region_size (int, optional): gives the minimal number of voxels a
            region has to have in order to be considered, default 100

    Returns:
        a list of regions, where each item is a binary ndarray with the same
        shape as the segmentation but contains one region
    """
    # Load the segmentation numpy array from a file and get only the requested
    # labels as 1 and the background as 0:
    seg = io.load_tomo(infile)
    assert(isinstance(seg, np.ndarray))
    data_type = seg.dtype
    binary_seg = (seg == lbl).astype(data_type)

    # If requested, close small holes in the segmentation:
    outfile = infile
    if close:
        outfile = ("%s%s_closed_size%s_iter%s.mrc"
                   % (infile[0:-4], lbl, close_cube_size, close_iter))
        if not isfile(outfile):
            from scipy import ndimage
            cube = np.ones((close_cube_size, close_cube_size, close_cube_size))
            binary_seg = ndimage.binary_closing(
                binary_seg, structure=cube, iterations=close_iter
            ).astype(data_type)
            # Write the closed binary segmentation into a file:
            io.save_numpy(binary_seg, outfile)
            print ("Closed the binary segmentation and saved it into the file "
                   "%s" % outfile)
        else:  # the '.mrc' file already exists
            binary_seg = io.load_tomo(outfile)
            print ("The closed binary segmentation was loaded from the file "
                   "%s" % outfile)

    # Label each connected region of the binary segmentation:
    label_seg = label(binary_seg)

    # Get only regions with at least the given size:
    regions = []
    for i, region in enumerate(regionprops(label_seg)):
        region_area = region.area
        if region_area >= min_region_size:
            print "%s. region has %s voxels and pass" % (i + 1, region_area)
            # Get the region coordinates and make an ndarray with same shape as
            # the segmentation and 1 at those coordinates:
            region_ndarray = np.zeros(shape=tuple(seg.shape), dtype=data_type)
            # 2D array with 3 columns: x, y, z and number of rows corresponding
            # to the number of voxels in the region
            region_coords = region.coords
            for i in xrange(region_coords.shape[0]):  # iterate over the rows
                region_ndarray[region_coords[i, 0],
                               region_coords[i, 1],
                               region_coords[i, 2]] = 1
            regions.append(region_ndarray)
        else:
            print ("%s. region has %s voxels and does NOT pass"
                   % (i + 1, region_area))
    print "%s regions passed." % len(regions)
    return regions, outfile
Пример #5
0
def run_gen_surface(tomo,
                    outfile_base,
                    lbl=1,
                    mask=True,
                    save_input_as_vti=False,
                    verbose=False):
    """
    Runs pysurf_io.gen_surface function, which generates a VTK PolyData triangle
    surface for objects in a segmented volume with a given label.

    Removes triangles with zero area, if any are present, from the resulting
    surface.

    Args:
        tomo (str or numpy.ndarray): segmentation input file in one of the
            formats: '.mrc', '.em' or '.vti', or 3D array containing the
            segmentation
        outfile_base (str): the path and filename without the ending for saving
            the surface (ending '.surface.vtp' will be added automatically)
        lbl (int, optional): the label to be considered, 0 will be ignored,
            default 1
        mask (boolean, optional): if True (default), a mask of the binary
            objects is applied on the resulting surface to reduce artifacts
        save_input_as_vti (boolean, optional): if True (default False), the
            input is saved as a '.vti' file ('<outfile_base>.vti')
        verbose (boolean, optional): if True (default False), some extra
            information will be printed out

    Returns:
        the triangle surface (vtk.PolyData)
    """
    t_begin = time.time()

    # Generating the surface (vtkPolyData object)
    surface = io.gen_surface(tomo, lbl=lbl, mask=mask, verbose=verbose)

    # Filter out triangles with area=0, if any are present
    surface = __filter_null_triangles(surface, verbose=verbose)

    t_end = time.time()
    duration = t_end - t_begin
    print 'Surface generation took: %s min %s s' % divmod(duration, 60)

    # Writing the vtkPolyData surface into a VTP file
    io.save_vtp(surface, outfile_base + '.surface.vtp')
    print 'Surface was written to the file %s.vtp' % outfile_base

    if save_input_as_vti is True:
        # If input is a file name, read in the segmentation array from the file:
        if isinstance(tomo, str):
            tomo = io.load_tomo(tomo)
        elif not isinstance(tomo, np.ndarray):
            error_msg = 'Input must be either a file name or a ndarray.'
            raise pexceptions.PySegInputError(expr='run_gen_surface',
                                              msg=error_msg)

        # Save the segmentation as VTI for opening it in ParaView:
        io.save_numpy(tomo, outfile_base + '.vti')
        print 'Input was saved as the file %s.vti' % outfile_base

    return surface