예제 #1
0
def fourier_transform(v,
                      step=None,
                      subregion=None,
                      model_id=None,
                      phase=False):

    m = v.matrix(step=step, subregion=subregion)
    from numpy.fft import fftn
    cftm = fftn(m)  # Complex128 result, same array size as input

    from numpy import absolute, angle, float32
    if phase:
        aftm = angle(cftm).astype(float32)  # Radians
    else:
        aftm = absolute(cftm).astype(float32)
        aftm *= 1.0 / aftm.size  # Normalization
        aftm[0, 0,
             0] = 0  # Constant term often huge making histogram hard to use
    cftm = None  # Release memory
    ftm = fftshift(aftm)
    aftm = None  # Release memory

    # Place FT centered on data, scaled to keep same volume
    xyz_min, xyz_max = v.xyz_bounds()
    xyz_center = map(lambda a, b: 0.5 * (a + b), xyz_min, xyz_max)
    ijk_size = list(ftm.shape)
    ijk_size.reverse()

    if step is None:
        ijk_step = v.region[2]
    elif isinstance(step, int):
        ijk_step = (step, step, step)
    else:
        ijk_step = step
    xyz_size = [a - b for a, b in zip(xyz_max, xyz_min)]
    vol = xyz_size[0] * xyz_size[1] * xyz_size[2]
    cell_size = [a * b for a, b in zip(v.data.step, ijk_step)]
    cell_vol = cell_size[0] * cell_size[1] * cell_size[2]
    scale = pow(vol * cell_vol, 1.0 / 3)
    step = [scale / a for a in xyz_size]
    origin = [c - 0.5 * s * z for c, s, z in zip(xyz_center, step, ijk_size)]

    from chimerax.map_data import ArrayGridData
    ftd = ArrayGridData(ftm, origin, step)
    ftd.name = v.name + (' FT phase' if phase else ' FT')
    from chimerax.map import volume_from_grid_data
    ftr = volume_from_grid_data(ftd, v.session, model_id=model_id)
    ftr.copy_settings_from(v,
                           copy_thresholds=False,
                           copy_colors=False,
                           copy_region=False)
    ftr.set_parameters(show_outline_box=True)

    v.display = False  # Hide original map

    return ftr
예제 #2
0
def tile_planes(v, axis = 'z', pstep = 1, trim = 0,
                rows = None, columns = None, fill_order = 'ulh',
                step = None, subregion = None, model_id = None):

  vreg = v.subregion(step = step, subregion = subregion)
  reg = [list(ijk) for ijk in vreg]
  ac,ar,a = {'x':(1,2,0), 'y':(2,0,1), 'z':(0,1,2)}[axis]
  reg[0][a] += trim
  reg[1][a] -= trim
  reg[2][a] = pstep
  dorigin, dstep = v.region_origin_and_step(reg)
  
  m = v.region_matrix(reg)

  tcount = m.shape[2-a]
  if tcount == 0:
    return

  if rows is None and columns is None:
    # Choose columns to make square aspect ratio.
    w,h = m.shape[2-ac]*dstep[ac], m.shape[2-ar]*dstep[ar]
    from math import sqrt, ceil
    columns = min(tcount, int(ceil(sqrt(tcount*float(h)/w))))
    rows = (tcount - 1 + columns) // columns
  elif rows is None:
    rows = (tcount - 1 + columns) // columns
  elif columns is None:
    columns = (tcount - 1 + rows) // rows

  s0, s1, s2 = m.shape
  if axis == 'z': tshape = (1,rows*s1,columns*s2)
  elif axis == 'y': tshape = (columns*s0,1,rows*s2)
  elif axis == 'x': tshape = (rows*s0,columns*s1,1)
  from numpy import zeros
  ta = zeros(tshape, m.dtype)

  for i in range(tcount):
    # Start with top image in upper left corner.
    p,r,c = tile_position(i, rows, columns, tcount, fill_order)
    if axis == 'z':
      ta[0,r*s1:(r+1)*s1,c*s2:(c+1)*s2] = m[p,:,:]
    elif axis == 'y':
      ta[c*s0:(c+1)*s0,0,r*s2:(r+1)*s2] = m[:,p,:]
    elif axis == 'x':
      ta[r*s0:(r+1)*s0,c*s1:(c+1)*s1,0] = m[:,:,p]

  from chimerax.map_data import ArrayGridData
  td = ArrayGridData(ta, dorigin, dstep)
  td.name = v.name + ' tiled %s' % axis
  from chimerax.map import volume_from_grid_data
  tv = volume_from_grid_data(td, v.session, model_id = model_id)
  tv.copy_settings_from(v, copy_region = False, copy_active = False,
                        copy_xform = open)
  v.display = False          # Hide original map

  return tv
예제 #3
0
def flattened_grid(volume,
                   method='multiply linear',
                   step=1,
                   subregion=None,
                   region=None,
                   fitregion=None,
                   task=None):

    v = volume
    if region is None:
        region = v.subregion(step, subregion)

    m = v.region_matrix(region).copy()
    if fitregion:
        fregion = v.subregion(step, fitregion)
        mfit = v.region_matrix(fregion)
        moffset = [i - fi for i, fi in zip(region[0], fregion[0])]
    else:
        mfit = m
        moffset = (0, 0, 0)
    flatten_matrix(m, method, mfit, moffset, task=task)

    from chimerax.map_data import ArrayGridData
    d = v.data
    if v.name.endswith('flat'): name = v.name
    else: name = '%s flat' % v.name
    forigin, fstep = v.region_origin_and_step(region)
    fg = ArrayGridData(m, forigin, fstep, d.cell_angles, d.rotation, name=name)
    return fg
예제 #4
0
def variance(session, maps):
    sum = sum2 = None
    for v in maps:
        from numpy import float32
        m = v.full_matrix().astype(float32)
        if sum is None:
            sum = m.copy()
            sum2 = m * m
        else:
            if m.shape != sum.shape:
                from chimerax.core.errors import UserError
                raise UserError('Map %s' % v.name_with_id() +
                                ' size (%d,%d,%d)' % tuple(v.data.size) +
                                ' does not match map %s' %
                                maps[0].name_with_id() +
                                ' size (%d,%d,%d)' % tuple(maps[0].data.size))
            sum += m
            sum2 += m * m
    n = len(maps)
    var = sum2 / n - (sum * sum) / (n * n)
    d = maps[0].data
    from chimerax.map_data import ArrayGridData
    grid = ArrayGridData(var,
                         origin=d.origin,
                         step=d.step,
                         cell_angles=d.cell_angles,
                         rotation=d.rotation,
                         name='variance of %d maps' % n)
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(grid, session)
    return v
예제 #5
0
def ones_volume(surfaces,
                pad,
                spacing,
                border,
                default_size=100,
                value_type=None):

    # Figure out array size
    bounds = scene_bounds(surfaces)
    bsize = [s + 2 * pad + 2 * border for s in bounds.size()]
    if spacing is None:
        s = max(bsize) / default_size
        spacing = (s, s, s)
    from math import ceil
    size = [1 + int(ceil(s / sp)) for s, sp in zip(bsize, spacing)]
    origin = [x - (pad + border) for x in bounds.xyz_min]

    # Create ones array
    from numpy import ones, int8
    vtype = int8 if value_type is None else value_type
    varray = ones(size[::-1], vtype)
    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(varray, origin, spacing, name='mask')

    # Create Volume model
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(g,
                              surfaces[0].session,
                              open_model=False,
                              show_dialog=False)

    return v
예제 #6
0
 def _generate_data_array(self, origin, grid_origin, dim):
     data = self._data_fill_target = numpy.empty(dim, numpy.float32)
     order = numpy.array([2, 1, 0], int)
     from chimerax.map_data import ArrayGridData
     darray = ArrayGridData(data.transpose(),
                            origin=origin,
                            step=self.voxel_size,
                            cell_angles=self.cell.angles_deg)
     return darray
예제 #7
0
def mlp_map(session, atoms, method, spacing, max_dist, nexp, name, open_map):
    data, bounds = calculatefimap(atoms, method, spacing, max_dist, nexp)

    # m.pot is 1-dimensional if m.writedxfile() was called.  Has indices in x,y,z order.
    origin = tuple(xmin for xmin, xmax in bounds)
    s = spacing
    step = (s, s, s)
    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(data, origin, step, name=name)
    g.polar_values = True
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(g,
                              session,
                              open_model=open_map,
                              show_dialog=open_map)
    if open_map:
        v.update_drawings()  # Compute surface levels
        v.set_parameters(
            surface_colors=[(0, 139 / 255, 139 / 255,
                             1), (184 / 255, 134 / 255, 11 / 255, 1)])
    return v
예제 #8
0
def unbend_volume(volume,
                  path,
                  yaxis,
                  xsize,
                  ysize,
                  grid_spacing,
                  subregion='all',
                  step=1,
                  model_id=None):

    # Compute correctly spaced cubic splined path points.
    points = spline_path(path, grid_spacing)
    axes = path_point_axes(points, yaxis)
    nx = int(xsize / grid_spacing) + 1
    ny = int(ysize / grid_spacing) + 1
    nz = len(points)

    # Create a rectangle of point positions to interpolate at.
    from numpy import empty, float32, arange
    section = empty((ny, nx, 3), float32)
    x = arange(nx, dtype=float32) * grid_spacing - 0.5 * (xsize - 1.0)
    y = arange(ny, dtype=float32) * grid_spacing - 0.5 * (ysize - 1.0)
    for j in range(ny):
        section[j, :, 0] = x
    for i in range(nx):
        section[:, i, 1] = y
    section[:, :, 2] = 0
    s = section.reshape((ny * nx, 3))

    # Interpolate planes to fill straightened array.
    from chimerax.geometry import translation
    m = empty((nz, ny, nx), float32)
    for k in range(nz):
        tf = translation(points[k]) * axes[k]
        m[k, :, :] = volume.interpolated_values(s,
                                                tf,
                                                subregion=subregion,
                                                step=step).reshape((ny, nx))

    # Create volume.
    from chimerax.map_data import ArrayGridData
    step = [grid_spacing] * 3
    origin = [0, 0, 0]
    g = ArrayGridData(m, origin, step, name='unbend')
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(g, volume.session, model_id=model_id)
    v.copy_settings_from(volume,
                         copy_region=False,
                         copy_active=False,
                         copy_xform=open)

    return v
예제 #9
0
def laplacian(v, step=None, subregion=None, model_id=None):

    m = v.matrix(step=step, subregion=subregion)

    from numpy import float32, multiply, add
    lm = m.astype(float32)  # Copy array
    multiply(lm, -6.0, lm)
    add(lm[:-1, :, :], m[1:, :, :], lm[:-1, :, :])
    add(lm[1:, :, :], m[:-1, :, :], lm[1:, :, :])
    add(lm[:, :-1, :], m[:, 1:, :], lm[:, :-1, :])
    add(lm[:, 1:, :], m[:, :-1, :], lm[:, 1:, :])
    add(lm[:, :, :-1], m[:, :, 1:], lm[:, :, :-1])
    add(lm[:, :, 1:], m[:, :, :-1], lm[:, :, 1:])

    lm[0, :, :] = 0
    lm[-1, :, :] = 0
    lm[:, 0, :] = 0
    lm[:, -1, :] = 0
    lm[:, :, 0] = 0
    lm[:, :, -1] = 0

    origin, step = v.data_origin_and_step(subregion=subregion, step=step)
    d = v.data
    from chimerax.map_data import ArrayGridData
    ld = ArrayGridData(lm,
                       origin,
                       step,
                       d.cell_angles,
                       d.rotation,
                       name=v.name + ' Laplacian')
    ld.polar_values = True
    from chimerax.map import volume_from_grid_data
    lv = volume_from_grid_data(ld, v.session, model_id=model_id)
    lv.copy_settings_from(v, copy_thresholds=False, copy_colors=False)
    lv.set_parameters(cap_faces=False)

    v.display = False  # Hide original map

    return lv
예제 #10
0
def lattice_models(session, seg, max_surfaces=100):
    # Map lattice id to dictionary mapping segment index to (descrip, color)
    lattice_segs = {}
    for segment in seg.segments:
        v = segment.three_d_volume
        if v is not None:
            lseg = lattice_segs.setdefault(v.lattice_id, {})
            if v.value is not None:
                lseg[int(v.value)] = (segment.biological_annotation,
                                      segment.colour)

    scale, shift = guess_scale_and_shift(seg)

    # Create Volume model of segment indices for each lattice.
    models = []
    lattices = seg.lattices
    for i, lattice in enumerate(lattices):
        d = lattice.data_array  # Docs say number array, but emd 1547 gives bytes
        name = 'region map' if len(lattices) == 1 else 'region map %d' % i
        from chimerax.map_data import ArrayGridData
        g = ArrayGridData(d, step=scale, origin=shift, name=name)
        from chimerax.map import volume_from_grid_data
        v = volume_from_grid_data(g, session, open_model=False)
        v.display = False
        if lattice.id in lattice_segs:
            v.segments = lseg = lattice_segs[lattice.id]
            set_segmentation_image_colors(v, lseg)
            # Make a surface for each segment.
            regions = list(lseg.items())
            regions.sort()
            surfs = [
                segment_surface(v, sindex, descrip, color)
                for sindex, (descrip, color) in regions[:max_surfaces]
            ]
            if surfs:
                ns, nr = len(surfs), len(regions)
                sname = ('%d surfaces' %
                         ns) if ns == nr else ('%d of %d surfaces' % (ns, nr))
                from chimerax.core.models import Model
                surf_group = Model(sname, v.session)
                surf_group.add(surfs)
                models.append(surf_group)
        # TODO: Don't see how to get the transform id for the lattice.
        #  EMD 1547 segmentation has two transforms, identity and the
        #  map transform (2.8A voxel size, shift to center) but I didn't
        #  find any place where transform 1 is associated with the lattice.
        #  Appears it should be in segment.three_d_volume.transform_id but this
        #  attribute is optional and is None in this case.
        models.append(v)

    return models
예제 #11
0
def bounding_grid(xyz, step, pad, transforms=None):
    from chimerax.geometry import bounds
    b = bounds.point_bounds(xyz, transforms)
    origin = [x - pad for x in b.xyz_min]
    from math import ceil
    shape = [
        int(ceil((b.xyz_max[a] - b.xyz_min[a] + 2 * pad) / step))
        for a in (2, 1, 0)
    ]
    from numpy import zeros, float32
    matrix = zeros(shape, float32)
    from chimerax.map_data import ArrayGridData
    grid = ArrayGridData(matrix, origin, (step, step, step))
    return grid
예제 #12
0
def ridge_grid(volume, level=None, step=1, subregion=None):

    v = volume
    region = v.subregion(step, subregion)

    m = v.region_matrix(region)
    rm = ridge_matrix(m, level)

    from chimerax.map_data import ArrayGridData
    d = v.data
    name = '%s ridges' % v.name
    origin, step = v.region_origin_and_step(region)
    rg = ArrayGridData(rm, origin, step, d.cell_angles, d.rotation, name=name)
    return rg
예제 #13
0
def falloff_grid(volume, iterations = 10, step = 1, subregion = None):

    v = volume
    region = v.subregion(step, subregion)

    from numpy import float32
    m = v.region_matrix(region).astype(float32)
    falloff_matrix(m, iterations)

    from chimerax.map_data import ArrayGridData
    d = v.data
    name = '%s falloff' % v.name
    forigin, fstep = v.region_origin_and_step(region)
    fg = ArrayGridData(m, forigin, fstep, d.cell_angles, d.rotation,
                       name = name)
    return fg
예제 #14
0
def map_covering_box(v, ijk_min, ijk_max, ijk_cell_size, symmetries, step):

    d = v.data
    if ijk_cell_size == d.size and (symmetries is None
                                    or len(symmetries) == 0):
        # Full unit cell and no symmetries to average.
        g = v.grid_data(subregion='all', step=step, mask_zone=False)
        from chimerax.map import volume
        cg = volume.map_from_periodic_map(g, ijk_min, ijk_max)
        return cg

    out_ijk_size = tuple(a - b + 1 for a, b in zip(ijk_max, ijk_min))
    from chimerax.geometry import translation
    out_ijk_to_vijk_transform = translation(ijk_min)

    ijk_symmetries = ijk_symmetry_matrices(d, symmetries)

    from numpy import empty, float32
    shape = list(reversed(out_ijk_size))
    m = empty(shape, float32)

    from chimerax.map import extend_crystal_map
    nnc, dmax = extend_crystal_map(v.full_matrix(), ijk_cell_size,
                                   ijk_symmetries.array(), m,
                                   out_ijk_to_vijk_transform.matrix)

    log = v.session.logger
    log.info(
        'Extended map %s to box of size (%d, %d, %d),\n' %
        ((v.name, ) + out_ijk_size) +
        '  cell size (%d, %d, %d) grid points, %d symmetry operations,\n' %
        (tuple(ijk_cell_size) + (len(ijk_symmetries), )) +
        '  %d points not covered by any symmetry,\n' % nnc +
        '  maximum value difference where symmetric map copies overlap = %.5g\n'
        % dmax)
    if nnc > 0:
        log.status('%d grid points not covered' % nnc)

    origin = d.ijk_to_xyz(ijk_min)
    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(m,
                      origin,
                      d.step,
                      d.cell_angles,
                      name=v.name + ' extended')

    return g
예제 #15
0
def sphere_volume(session, n, r, noise=1.0):

    from numpy import indices, single as floatc
    o = 0.5 * (n - 1)
    i = indices((n, n, n), floatc) - o
    a = (i[0, ...] * i[0, ...] + i[1, ...] * i[1, ...] + i[2, ...] * i[2, ...]
         < r * r).astype(floatc)

    if noise > 0:
        from numpy.random import normal
        a += normal(0, noise, a.shape)

    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(a, origin=(-o, -o, -o), step=(1, 1, 1), name='sphere')
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(g, session)
    return v
예제 #16
0
    def _generate_data_array(self, coords, step, radius, pad=0):
        import numpy
        if hasattr(step, '__len__'):
            step = min(step)

        step = max((step, radius / 4))
        step = min(step, 1.5)
        step = numpy.ones(3) * step
        cmin = coords.min(axis=0)
        cmax = coords.max(axis=0)
        mincoor = cmin - radius - pad
        maxcoor = cmax + radius + pad
        dim = numpy.ceil((maxcoor - mincoor) / step).astype(numpy.int)
        data = numpy.zeros(dim, numpy.uint8)
        self._data_fill_target = data
        from chimerax.map_data import ArrayGridData
        darray = ArrayGridData(data.transpose(), origin=mincoor, step=step)
        return darray
예제 #17
0
def unroll_operation(v, r0, r1, h, center, axis, gsp, subregion, step,
                     modelId):

    from math import ceil, pi
    zsize = int(max(1, ceil(h / gsp)))  # cylinder height
    xsize = int(max(1, ceil((r1 - r0) / gsp)))  # slab thickness
    rmid = 0.5 * (r0 + r1)
    circum = rmid * 2 * pi
    ysize = int(max(1, ceil(circum / gsp)))  # circumference

    from chimerax.geometry import normalize_vector
    axis = normalize_vector(axis)
    agrid_points = annulus_grid(r0, r1, center, axis, ysize, xsize)
    grid_points = agrid_points.reshape((ysize * xsize, 3))
    grid_points[:] += tuple([-0.5 * h * ai for ai in axis])  # Shift annulus.
    from numpy import empty
    values = empty((zsize, ysize, xsize), v.data.value_type)
    axis_step = tuple([h * float(ai) / (zsize - 1) for ai in axis])
    for i in range(zsize):
        vval = v.interpolated_values(grid_points,
                                     subregion=subregion,
                                     step=step)
        values[i, :, :] = vval.reshape((ysize, xsize))
        grid_points[:] += axis_step  # Shift annulus.

    from chimerax.map_data import ArrayGridData
    gstep = (float(r1 - r0) / (xsize - 1), circum / (ysize - 1),
             float(h) / (zsize - 1))
    gorigin = (center[0] + r0, center[1] - 0.5 * circum, center[2] - 0.5 * h)
    g = ArrayGridData(values, gorigin, gstep, name='unrolled %s' % v.name)
    from chimerax.map import volume_from_grid_data
    vu = volume_from_grid_data(g, v.session, model_id=modelId)
    vu.copy_settings_from(v,
                          copy_region=False,
                          copy_active=False,
                          copy_colors=False)

    if axis[0] != 0 or axis[1] != 0:
        # Rotate so unrolled volume is tangential to cylinder
        from chimerax.geometry import orthonormal_frame
        vu.position = v.position * orthonormal_frame(axis)

    return vu
예제 #18
0
def array_to_model(mvol, volume, ijk_origin, model_id):

    # Create masked volume grid object.
    from chimerax.map_data import ArrayGridData
    g = volume.data
    morigin = g.ijk_to_xyz_transform * ijk_origin
    m = ArrayGridData(mvol,
                      morigin,
                      g.step,
                      cell_angles=g.cell_angles,
                      rotation=g.rotation,
                      name=g.name + ' masked')

    # Create masked volume object.
    from chimerax.map import volume_from_grid_data
    v = volume_from_grid_data(m, volume.session, model_id=model_id)
    v.copy_settings_from(volume, copy_region=False)
    v.show()

    return v
예제 #19
0
def threshold_grid(volume,
                   minimum=None,
                   set_minimum=None,
                   maximum=None,
                   set_maximum=None,
                   step=1,
                   subregion=None,
                   region=None):

    v = volume
    if region is None:
        region = v.subregion(step, subregion)

    origin, step = v.region_origin_and_step(region)

    m = v.region_matrix(region).copy()

    import numpy
    from numpy import array, putmask
    if not minimum is None:
        t = array(minimum, m.dtype)
        if set_minimum is None or set_minimum == minimum:
            numpy.maximum(m, t, m)
        else:
            putmask(m, m < t, array(set_minimum, m.dtype))
    if not maximum is None:
        t = array(maximum, m.dtype)
        if set_maximum is None or set_maximum == maximum:
            numpy.minimum(m, t, m)
        else:
            putmask(m, m > t, array(set_maximum, m.dtype))

    from chimerax.map_data import ArrayGridData
    d = v.data
    if v.name.endswith('thresholded'): name = v.name
    else: name = '%s thresholded' % v.name
    tg = ArrayGridData(m, origin, step, d.cell_angles, d.rotation, name=name)
    return tg
예제 #20
0
def local_correlation(map1, map2, window_size, subtract_mean, model_id=None):

    d1 = map1.data
    m1 = map1.full_matrix()
    d2 = map2.data
    m2, same = map2.interpolate_on_grid(map1)
    mc = local_correlation_matrix(m1, m2, window_size, subtract_mean)

    hs = 0.5 * (window_size - 1)
    origin = tuple(o + hs * s for o, s in zip(d1.origin, d1.step))
    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(mc,
                      origin,
                      d1.step,
                      d1.cell_angles,
                      d2.rotation,
                      name='local correlation')

    from chimerax.map import volume_from_grid_data
    mapc = volume_from_grid_data(g, map1.session, model_id=model_id)
    mapc.position = map1.position

    return mapc
예제 #21
0
def gaussian_grid(volume, sdev, step = 1, subregion = None, region = None,
                  value_type = None, invert = False, task = None):

  v = volume
  if region is None:
    region = v.subregion(step, subregion)

  origin, step = v.region_origin_and_step(region)

  sdev3 = (sdev,sdev,sdev) if isinstance(sdev,(float,int)) else sdev
  ijk_sdev = [float(sd)/s for sd,s in zip(sdev3,step)]

  m = v.region_matrix(region)
  gm = gaussian_convolution(m, ijk_sdev, value_type = value_type,
                            invert = invert, task = task)

  from chimerax.map_data import ArrayGridData
  d = v.data
  if v.name.endswith('gaussian'): name = v.name
  else:                           name = '%s gaussian' % v.name
  gg = ArrayGridData(gm, origin, step, d.cell_angles, d.rotation,
                     name = name)
  return gg
예제 #22
0
def median_grid(volume,
                bin_size=3,
                iterations=1,
                step=1,
                subregion=None,
                region=None):

    v = volume
    if region is None:
        region = v.subregion(step, subregion)

    origin, step = v.region_origin_and_step(region)

    vm = v.region_matrix(region)
    m = vm
    for i in range(iterations):
        m = median_array(m, bin_size)

    from chimerax.map_data import ArrayGridData
    d = v.data
    if v.name.endswith('median'): name = v.name
    else: name = '%s median' % v.name
    mg = ArrayGridData(m, origin, step, d.cell_angles, d.rotation, name=name)
    return mg
예제 #23
0
def processed_volume(v, subregion = None, step = None, value_type = None, threshold = None,
                     zero_mean = False, scale_factor = None, match_scale = None,
                     enclose_volume = None, fast_enclose_volume = None, normalize_level = None,
                     align_to = None, on_grid = None, mask = None, final_value_type = None):
    d = v.data
    region = None
    if not subregion is None or not step is None:
        from chimerax.map.volume import full_region
        ijk_min, ijk_max = full_region(d.size)[:2] if subregion is None else subregion
        ijk_step = (1,1,1) if step is None else step
        region = (ijk_min, ijk_max, ijk_step)
        from chimerax.map_data import GridSubregion
        d = GridSubregion(d, ijk_min, ijk_max, ijk_step)

    if (value_type is None and threshold is None and not zero_mean and
        scale_factor is None and match_scale is None and align_to is None and
        mask is None and final_value_type is None):
        return d

    m = d.full_matrix()
    if not value_type is None:
        m = m.astype(value_type)

    if not threshold is None:
        from numpy import array, putmask
        t = array(threshold, m.dtype)
        putmask(m, m < t, 0)

    if zero_mean:
        from numpy import float64
        mean = m.mean(dtype = float64)
        m = (m - mean).astype(m.dtype)

    if not scale_factor is None:
        m = (m*scale_factor).astype(m.dtype)

    if not match_scale is None:
        ms = match_scale.region_matrix(region) if region else match_scale.full_matrix()
        from numpy import float64, einsum
        m1, ms1 = m.sum(dtype = float64), ms.sum(dtype = float64)
        m2, ms2, mms = einsum('ijk,ijk',m,m,dtype=float64), einsum('ijk,ijk',ms,ms,dtype=float64), einsum('ijk,ijk',m,ms,dtype=float64)
        n = m.size
        a = (mms - m1*ms1/n) / (m2 - m1*m1/n)
        b = (ms1 - a*m1) / n
        am = a*m
        am += b
        print ('scaling #%s' % v.id_string, a, b, m1, ms1, m2, ms2, mms, am.mean(), am.std(), ms.mean(), ms.std())
        m[:] = am.astype(m.dtype)

    if not enclose_volume is None or not fast_enclose_volume is None:
        set_enclosed_volume(v, enclose_volume, fast_enclose_volume)

    if not normalize_level is None:
        level = v.maximum_surface_level
        if level is None:
            from chimerax.core.errors import UserError
            raise UserError('vseries save: normalize_level used but no level set for volume %s' % v.name)
        if zero_mean:
            level -= mean
        scale = normalize_level / level
        m = (m*scale).astype(m.dtype)

    if not align_to is None:
        align(v, align_to)

    if not on_grid is None:
        vc = v.writable_copy(value_type = m.dtype, unshow_original = False)
        vc.full_matrix()[:,:,:] = m
        m = on_grid.full_matrix()
        m[:,:,:] = 0
        on_grid.add_interpolated_values(vc)
        vc.close()
        d = on_grid.data

    if not mask is None:
        m[:,:,:] *= mask.full_matrix()

    if not final_value_type is None:
        m = m.astype(final_value_type)

    from chimerax.map_data import ArrayGridData
    d = ArrayGridData(m, d.origin, d.step, d.cell_angles, d.rotation)

    return d
예제 #24
0
def matching_grid(grid):
    from numpy import zeros, float32
    matrix = zeros(grid.full_matrix().shape, float32)
    from chimerax.map_data import ArrayGridData
    g = ArrayGridData(matrix, grid.origin, grid.step)
    return g
예제 #25
0
def grid_data_from_state(s, gdcache, session, file_paths):

  if 'array' in s:
    from numpy import frombuffer, dtype
    from gzip import decompress
    from base64 import b64decode
    a = frombuffer(decompress(b64decode(s['array'])), dtype = dtype(s['value_type']))
    if not a.flags.writeable:
      a = a.copy()
    array = a.reshape(s['size'][::-1])
    from chimerax.map_data import ArrayGridData
    dlist = [ArrayGridData(array)]
  else:
    dbfetch = s.get('database_fetch')
    ask = (dbfetch is None)
    if s.get('series_index',0) >= 1 or s.get('time',0) >= 1:
      ask = False
    path = absolute_path(s['path'], file_paths, ask = ask,
                         base_path = session.session_file_path)
    empty_path = (path is None or path == '' or path == () or path == [])
    if empty_path and dbfetch is None:
      return None
    else:
      gid = s.get('grid_id','')
      file_type = s['file_type']
      dlist = open_data(path, gid, file_type, dbfetch, gdcache, session)

  for data in dlist:
    data.name = s['name']

  if 'xyz_step' in s:
    for data in dlist:
      data.set_step(s['xyz_step'])

  if 'xyz_origin' in s:
    for data in dlist:
      data.set_origin(s['xyz_origin'])

  if 'cell_angles' in s:
    for data in dlist:
      data.set_cell_angles(s['cell_angles'])

  if 'rotation' in s:
    for data in dlist:
      data.set_rotation(s['rotation'])

  if 'symmetries' in s:
    for data in dlist:
      data.symmetries = s['symmetries']

  if 'series_index' in s:
    for data in dlist:
      data.series_index = s['series_index']

  if 'channel' in s:
    for data in dlist:
      data.channel = s['channel']

  if 'time' in s:
    for data in dlist:
      data.time = s['time']
      
  if 'available_subsamplings' in s:
    # Subsamples may be from separate files or the same file.
    from chimerax.map_data import SubsampledGrid
    dslist = []
    for data in dlist:
      if not isinstance(data, SubsampledGrid):
        data = SubsampledGrid(data)
      dslist.append(data)
    dlist = dslist
    for cell_size, dstate in s['available_subsamplings'].items():
      dpath = absolute_path(dstate.path, file_paths, base_path = session.session_file_path)
      if dpath != path:
        # TODO: This looks wrong.  Don't we just recurse calling grid_data_from_state()?
        ssdlist = dstate.create_object(gdcache)
        for i,ssdata in enumerate(ssdlist):
          dlist[i].add_subsamples(ssdata, cell_size)

  return dlist