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

  if v is None:
    from VolumeViewer import active_volume
    v = active_volume()
    if v is None:
      return

  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, float32
  aftm = absolute(cftm).astype(float32)
  cftm = None           # Release memory
  aftm *= 1.0/aftm.size
  aftm[0,0,0] = 0       # Constant term often huge making histogram hard to use
  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 = map(lambda a,b: a-b, xyz_max, xyz_min)
  vol = xyz_size[0]*xyz_size[1]*xyz_size[2]
  cell_size = map(lambda a,b: a*b, 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 = map(lambda a: scale/a, xyz_size)
  origin = map(lambda c,s,z: c-0.5*s*z, xyz_center, step, ijk_size)

  from VolumeData import Array_Grid_Data
  ftd = Array_Grid_Data(ftm, origin, step)
  ftd.name = v.name + ' FT'
  from VolumeViewer import volume_from_grid_data
  ftr = volume_from_grid_data(ftd, show_data = False, model_id = model_id)
  ftr.copy_settings_from(v, copy_thresholds = False,  copy_colors = False,
                         copy_region = False)
  ftr.initialize_thresholds()
  ftr.set_parameters(show_outline_box = True)
  ftr.show()
  
  v.unshow()          # Hide original map

  return ftr
예제 #2
0
def export_mask(segmentation,
                savePath=None,
                format='mrc',
                binSize=(1, 1, 1),
                sequentialIds=True):

    m = segmentation.mask
    origin = segmentation.grid_origin()
    step = segmentation.grid_step()

    # Include only id numbers of top-level region groups.
    from numpy import zeros, empty
    parent = zeros((segmentation.max_region_id + 1, ), dtype=m.dtype)
    for r in segmentation.all_regions():
        parent[r.rid] = r.top_parent().rid
    if sequentialIds:
        used_ids = list(set(parent))
        used_ids.sort()
        seq_id = zeros((used_ids[-1] + 1, ), dtype=m.dtype)
        for i, id in enumerate(used_ids):
            seq_id[id] = i
        parent = seq_id[parent]
    array = parent[m]

    # Expand array to match unbinned density map size.
    if tuple(binSize) != (1, 1, 1):
        step = [float(s) / b for s, b in zip(step, binSize)]
        shape = [a * b for a, b in zip(array.shape, binSize[::-1])]
        aub = empty(shape, array.dtype)
        b2, b1, b0 = binSize
        for o0 in range(b0):
            for o1 in range(b1):
                for o2 in range(b2):
                    aub[o0::b0, o1::b1, o2::b2] = array
        array = aub

    from VolumeData import Array_Grid_Data
    g = Array_Grid_Data(array, origin, step)
    g.name = segmentation.name + ' region ids'

    if savePath is None:
        # Open mask map as a volume.
        import VolumeViewer
        v = VolumeViewer.volume_from_grid_data(g)
        v.openState.xform = segmentation.openState.xform
    else:
        # Write map file.
        from VolumeData import save_grid_data
        save_grid_data(g, savePath, format)

    return g
예제 #3
0
    def openVolume(self):
        try:
            while True:
                if self.vol_conn.poll():
                    
                    msg = self.vol_conn.recv()
                    if msg == 'open_volume':
                        data = self.vol_conn.recv()#objects are serialized by default
                        grid = Array_Grid_Data(data)
                        self.volume = volume_from_grid_data(grid)
                        
                    elif msg == 'voxel_size':
                        self.voxelSize = self.vol_conn.recv()
                        cmd = "volume #0 voxelSize %s"%self.voxelSize
                        runCommand(cmd)


                    elif msg == 'command_list':
                        commandList = self.vol_conn.recv()
                        for command in commandList:
                            runCommand(command)

                    elif msg == 'end':#if you don't break cicle volume is never shown
                        break

                else:
                    sleep(0.01)
        except EOFError:
            print ('Lost connection to client')
예제 #4
0
    def openVolume(self):
        try:
            while True:
                if self.remote_conn.poll():

                    msg = self.remote_conn.recv()
                    #print msg
                    if msg == 'open_volume':
                        data = self.remote_conn.recv()
                        print data
                        grid = Array_Grid_Data(data)
                        self.volume = volume_from_grid_data(grid)
                        #runCommand("volume #0 step 1")

                    elif msg == 'voxelSize':
                        voxelSize = self.remote_conn.recv()
                        cmd = "volume #0 voxelSize %s" % voxelSize
                        runCommand(cmd)
                        runCommand("focus")

                    elif msg == 'draw_angular_distribution':
                        angulardist = self.remote_conn.recv()
                        for command in angulardist:
                            runCommand(command)

                    elif msg == 'end':
                        break
                    else:
                        sleep(0.01)
        except EOFError:
            print 'Lost connection to client'
def create_geometric_model(shape_name, param_list):
    """
    Creates chimera model object from a geometric shape
    Centers model at center of frame (for future rotations)
    Model object is numbered #1
    
    :param shpae_name: one of known shapes - cube, sphere
    :param param_list: list of geomteric shape paramters (cube side, sphere radius..)
    """

    if shape_name == 'cube':
        matrix = create_cube_matrix(param_list)
    elif shape_name == 'sphere':
        matrix = create_sphere_matrix(param_list)
    elif shape_name == 'L':
        matrix = create_L_matrix(param_list)
    else:
        raise ('unkown shape!')

    # create model
    v = volume_from_grid_data(Array_Grid_Data(matrix))
    tmp_model = chimera.specifier.evalSpec('#0').models()[0]
    trans = tuple(np.array(tmp_model.openState.cofr.data()) * -1)
    tmp_model.openState.globalXform(euler_xform([0, 0, 0], trans))

    # change model number to #1 for consitency
    model = tmp_model.copy()
    tmp_model.close()
    return model
def laplacian(v = None, step = None, subregion = None, model_id = None):

  if v is None:
    from VolumeViewer import active_volume
    v = active_volume()
    if v is None:
      return 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 VolumeData import Array_Grid_Data
  ld = Array_Grid_Data(lm, origin, step, d.cell_angles, d.rotation,
                       name = v.name + ' Laplacian')
  ld.polar_values = True
  from VolumeViewer import volume_from_grid_data
  lv = volume_from_grid_data(ld, show_data = False, model_id = model_id)
  lv.copy_settings_from(v, copy_thresholds = False, copy_colors = False)
  lv.set_parameters(cap_faces = False)
  lv.initialize_thresholds()
  lv.show()
  
  v.unshow()          # Hide original map

  return lv
    def subregion_grid(self, voxel_size, xform, name):

        bm = self.box_model
        if bm is None or bm.box is None or bm.model() is None:
            return None

        # Deterime array size.  Use half voxel padding on all sides.
        elength = bm.edge_lengths()
        from math import ceil
        size = [
            max(1, int(ceil((elength[a] - voxel_size[a]) / voxel_size[a])))
            for a in (0, 1, 2)
        ]

        # Allocate array.
        from VolumeData import allocate_array
        array = allocate_array(size, zero_fill=True)

        # Determine origin, rotation, and cell angles.
        b2vxf = bm.xform()
        b2vxf.premultiply(xform.inverse())
        from Matrix import xform_matrix, apply_matrix, apply_matrix_without_translation, cell_angles_and_rotation
        b2v = xform_matrix(b2vxf)
        origin = apply_matrix(b2v, bm.origin())
        vaxes = [apply_matrix_without_translation(b2v, v) for v in bm.axes()]
        cell_angles, rotation = cell_angles_and_rotation(vaxes)

        # Create grid.
        from VolumeData import Array_Grid_Data
        g = Array_Grid_Data(array,
                            origin,
                            voxel_size,
                            cell_angles,
                            rotation,
                            name=name)

        # Add half voxel padding.
        g.set_origin(g.ijk_to_xyz((0.5, 0.5, 0.5)))

        return g
예제 #8
0
def masked_grid_data(grid_data, mask, mask_value = None):

  d = grid_data
  matrix = d.full_matrix()
  from numpy import zeros, putmask
  masked = zeros(matrix.shape, matrix.dtype)
  if mask_value is None:
    putmask(masked, mask, matrix)
  else:
    putmask(masked, mask == mask_value, matrix)

  from VolumeData import Array_Grid_Data
  masked_grid_data = Array_Grid_Data(masked, d.origin, d.step,
                                     d.cell_angles, d.rotation)
  return masked_grid_data
예제 #9
0
def make_normalized_map(data):
    
	from numpy import mean, std
	m = data.full_matrix()
     	mn = (m - m.mean()) / m.std() 
		
	from VolumeData import Array_Grid_Data
	dn = Array_Grid_Data(mn, data.data.origin, data.data.step, data.data.cell_angles,
    	                	data.data.rotation, name = data.data.name + ' normalized')

	from VolumeViewer import volume_from_grid_data
	vn = volume_from_grid_data(dn, show_data = False)
	vn.initialize_thresholds()
        vn.copy_settings_from(data)
        vn.data.symmetries = data.data.symmetries
	
        return vn 
예제 #10
0
def molecule_grid_data(atoms, resolution, step, pad, cutoff_range,
                       sigma_factor):

    from _multiscale import get_atom_coordinates, bounding_box
    xyz = get_atom_coordinates(atoms, transformed=True)

    # Transform coordinates to local coordinates of the molecule containing
    # the first atom.  This handles multiple unaligned molecules.
    from Matrix import xform_matrix
    m0 = atoms[0].molecule
    tf = xform_matrix(m0.openState.xform.inverse())
    from _contour import affine_transform_vertices
    affine_transform_vertices(xyz, tf)

    xyz_min, xyz_max = bounding_box(xyz)

    origin = [x - pad for x in xyz_min]
    ijk = (xyz - origin) / step
    anum = [a.element.number for a in atoms]
    sdev = sigma_factor * resolution / step
    from numpy import zeros, float32
    sdevs = zeros((len(atoms), 3), float32)
    sdevs[:] = sdev
    from math import pow, pi, ceil
    normalization = pow(2 * pi, -1.5) * pow(sdev * step, -3)
    shape = [
        int(ceil((xyz_max[a] - xyz_min[a] + 2 * pad) / step))
        for a in (2, 1, 0)
    ]
    matrix = zeros(shape, float32)

    from _gaussian import sum_of_gaussians
    sum_of_gaussians(ijk, anum, sdevs, cutoff_range, matrix)
    matrix *= normalization

    molecules = set([a.molecule for a in atoms])
    if len(molecules) > 1:
        name = 'molmap res %.3g' % (resolution, )
    else:
        name = 'molmap %s res %.3g' % (m0.name, resolution)

    from VolumeData import Array_Grid_Data
    grid = Array_Grid_Data(matrix, origin, (step, step, step), name=name)

    return grid, molecules
def gaussian_grid(volume, sdev, step = 1, subregion = None, region = None,
                  task = None):

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

  origin, step = v.region_origin_and_step(region)

  ijk_sdev = [sdev / s for s in step]

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

  from VolumeData import Array_Grid_Data
  d = v.data
  if v.name.endswith('gaussian'): name = v.name
  else:                           name = '%s gaussian' % v.name
  gg = Array_Grid_Data(gm, origin, step, d.cell_angles, d.rotation,
                       name = name)
  return gg
예제 #12
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 VolumeData import Array_Grid_Data
  d = v.data
  if v.name.endswith('median'): name = v.name
  else:                         name = '%s median' % v.name
  mg = Array_Grid_Data(m, origin, step, d.cell_angles, d.rotation,
                       name = name)
  return mg
    def openVolume(self):
        '''Wait for volume data and open in volume viewer'''
        try:
            while True:
                if self.remote_conn.poll():
                    msg = self.remote_conn.recv()
                    if type(msg) is numpy.ndarray:
                        from VolumeData import Array_Grid_Data
                        grid = Array_Grid_Data(msg)

                        from VolumeViewer import volume_from_grid_data
                        self.v = volume_from_grid_data(grid)
                        break

                    #else:
                    #print 'msg: ' + msg

                else:
                    time.sleep(0.01)
        except EOFError:
            print 'Lost connection to client'
            self.listener.close()
예제 #14
0
    def answer(self, msg):
        #print msg
        if msg == 'open_volume':
            data = self.vol_conn.recv()#objects are serialized by default
            #print data
            grid = Array_Grid_Data(data)
            self.volume = volume_from_grid_data(grid)
            self.centerVolume()


        elif msg == 'voxel_size':
            self.voxelSize = self.vol_conn.recv()
            cmd = "volume #0 voxelSize %s"%self.voxelSize
            #print cmd
            runCommand(cmd)
            runCommand("focus")
            #end debug

        elif msg == 'command_list':
            commandList = self.vol_conn.recv()
            for command in commandList:
                runCommand(command)
예제 #15
0
    def computeVolume(self,
                      atoms,
                      startFrame=None,
                      endFrame=None,
                      bound=None,
                      volumeName=None,
                      step=1,
                      spacing=0.5):
        # load and process frames
        if startFrame is None:
            startFrame = self.startFrame
        if endFrame is None:
            endFrame = self.endFrame
        if bound is not None:
            from _closepoints import find_close_points, BOXES_METHOD
        from Matrix import xform_matrix
        if self.holdingSteady:
            steadyAtoms, steadySel, steadyCS, inverse = \
                self.holdingSteady
            # all the above used later...
            inverse = xform_matrix(inverse)

        gridData = {}
        from math import floor
        from numpy import array, float32
        from _contour import affine_transform_vertices
        for fn in range(startFrame, endFrame + 1, step):
            cs = self.findCoordSet(fn)
            if not cs:
                self.status("Loading frame %d" % fn)
                self._LoadFrame(fn, makeCurrent=False)
                cs = self.findCoordSet(fn)

            self.status("Processing frame %d" % fn)
            pts = array([a.coord(cs) for a in atoms], float32)
            if self.holdingSteady:
                if bound is not None:
                    steadyPoints = array([a.coord(cs) for a in steadyAtoms],
                                         float32)
                    closeIndices = find_close_points(
                        BOXES_METHOD,
                        steadyPoints,
                        #otherPoints, bound)[1]
                        pts,
                        bound)[1]
                    pts = pts[closeIndices]
                try:
                    xf, inv = self.transforms[fn]
                except KeyError:
                    xf, inv = self.steadyXform(cs=cs)
                    self.transforms[fn] = (xf, inv)
                xf = xform_matrix(xf)
                affine_transform_vertices(pts, xf)
                affine_transform_vertices(pts, inverse)
            # add a half-voxel since volume positions are
            # considered to be at the center of their voxel
            from numpy import floor, zeros
            pts = floor(pts / spacing + 0.5).astype(int)
            for pt in pts:
                center = tuple(pt)
                gridData[center] = gridData.get(center, 0) + 1

        # generate volume
        self.status("Generating volume")
        axisData = zip(*tuple(gridData.keys()))
        minXyz = [min(ad) for ad in axisData]
        maxXyz = [max(ad) for ad in axisData]
        # allow for zero-padding on both ends
        dims = [maxXyz[axis] - minXyz[axis] + 3 for axis in range(3)]
        from numpy import zeros, transpose
        volume = zeros(dims, int)
        for index, val in gridData.items():
            adjIndex = tuple([index[i] - minXyz[i] + 1 for i in range(3)])
            volume[adjIndex] = val
        from VolumeData import Array_Grid_Data
        gd = Array_Grid_Data(
            volume.transpose(),
            # the "cushion of zeros" means d-1...
            [(d - 1) * spacing for d in minXyz],
            [spacing] * 3)
        if volumeName is None:
            volumeName = self.ensemble.name
        gd.name = volumeName

        # show volume
        self.status("Showing volume")
        import VolumeViewer
        dataRegion = VolumeViewer.volume_from_grid_data(gd)
        vd = VolumeViewer.volumedialog.volume_dialog(create=True)
        vd.message("Volume can be saved from File menu")

        self.status("Volume shown")
def masked_volume(volume,
                  surfaces,
                  projection_axis=(0, 0, 1),
                  full_map=False,
                  sandwich=False,
                  invert_mask=False):

    g = volume.data

    # Determine transform from vertex coordinates to depth array indices
    step = min(g.plane_spacings())
    fx, fy, fz = orthonormal_frame(projection_axis)
    from numpy import array, float32, intc, zeros, subtract
    tf = array(((fx[0], fx[1], fx[2], 0), (fy[0], fy[1], fy[2], 0),
                (fz[0], fz[1], fz[2], 0)), float32) / step

    # Transform vertices to depth array coordinates.
    zsurf = []
    tcount = 0
    for vertices, triangles in surfaces:
        varray = vertices.copy()
        apply_transform(tf, varray)
        zsurf.append((varray, triangles))
        tcount += len(triangles)
    if tcount == 0:
        return None
    vmin, vmax = bounding_box(zsurf)
    voffset = -(vmin - 0.5)
    tf[:, 3] += voffset
    from _contour import shift_vertices
    for varray, triangles in zsurf:
        shift_vertices(varray, voffset)
    from math import ceil, floor
    dxsize = int(ceil(vmax[0] - vmin[0] + 1))
    dysize = int(ceil(vmax[1] - vmin[1] + 1))

    # Create depth arrays
    depth = zeros((dysize, dxsize), float32)
    tnum = zeros((dysize, dxsize), intc)
    depth2 = zeros((dysize, dxsize), float32)
    tnum2 = zeros((dysize, dxsize), intc)

    # Create minimal size masked volume array and transformation from
    # masked volume indices to depth array indices.
    if full_map or invert_mask:
        from VolumeViewer.volume import full_region
        ijk_min, ijk_max = full_region(g.size)[:2]
    else:
        ijk_min, ijk_max = bounding_box(surfaces, g.xyz_to_ijk_transform)
        ijk_min = [int(floor(i)) for i in ijk_min]
        ijk_max = [int(ceil(i)) for i in ijk_max]
        from VolumeViewer.volume import clamp_region
        ijk_min, ijk_max = clamp_region((ijk_min, ijk_max, (1, 1, 1)),
                                        g.size)[:2]
    ijk_size = map(lambda a, b: a - b + 1, ijk_max, ijk_min)
    vol = g.matrix(ijk_min, ijk_size)
    mvol = zeros(vol.shape, vol.dtype)
    from Matrix import translation_matrix, multiply_matrices
    mijk_to_dijk = multiply_matrices(tf, g.ijk_to_xyz_transform,
                                     translation_matrix(ijk_min))

    # Copy volume to masked volume at masked depth intervals.
    max_depth = 1e37
    if sandwich:
        dlimit = .5 * max_depth
    else:
        dlimit = 2 * max_depth
    beyond = beyond_tnum = None
    max_layers = 200
    for iter in range(max_layers):
        depth.fill(max_depth)
        tnum.fill(-1)
        any = surfaces_z_depth(zsurf, depth, tnum, beyond, beyond_tnum)
        if not any:
            break
        depth2.fill(max_depth)
        tnum2.fill(-1)
        surfaces_z_depth(zsurf, depth2, tnum2, depth, tnum)
        from _mask import copy_slab
        copy_slab(depth, depth2, mijk_to_dijk, vol, mvol, dlimit)
        beyond = depth2
        beyond_tnum = tnum2

    if invert_mask:
        subtract(vol, mvol, mvol)

    # Create masked volume grid object.
    from VolumeData import Array_Grid_Data
    from Matrix import apply_matrix
    morigin = apply_matrix(g.ijk_to_xyz_transform, ijk_min)
    m = Array_Grid_Data(mvol,
                        morigin,
                        g.step,
                        cell_angles=g.cell_angles,
                        rotation=g.rotation,
                        name=g.name + ' masked')

    # Create masked volume object.
    from VolumeViewer import volume_from_grid_data
    v = volume_from_grid_data(m, show_data=False)
    v.copy_settings_from(volume, copy_region=False)
    v.show()
    volume.show(show=False)

    return v
예제 #17
0
	def computeVolume(self, atoms, startFrame=None, endFrame=None,
			bound=None, volumeName=None, step=1, spacing=0.5):
		# load and process frames
		if startFrame is None:
			startFrame = self.startFrame
		if endFrame is None:
			endFrame = self.endFrame
		if bound is not None:
			from _closepoints import find_close_points, BOXES_METHOD
		from Matrix import xform_matrix
		if self.holdingSteady:
			steadyAtoms, steadySel, steadyCS, inverse = \
							self.holdingSteady
			# all the above used later...
			inverse = xform_matrix(inverse)

		gridData = {}
		from math import floor
		from numpy import array, float32
		from _contour import affine_transform_vertices
		for fn in range(startFrame, endFrame+1, step):
			cs = self.findCoordSet(fn)
			if not cs:
				self.status("Loading frame %d" % fn)
				self._LoadFrame(fn, makeCurrent=False)
				cs = self.findCoordSet(fn)

			self.status("Processing frame %d" % fn)
			pts = array([a.coord(cs) for a in atoms], float32)
			if self.holdingSteady:
				if bound is not None:
					steadyPoints = array([a.coord(cs)
						for a in steadyAtoms], float32)
					closeIndices = find_close_points(
						BOXES_METHOD, steadyPoints,
						#otherPoints, bound)[1]
						pts, bound)[1]
					pts = pts[closeIndices]
				try:
					xf, inv = self.transforms[fn]
				except KeyError:
					xf, inv = self.steadyXform(cs=cs)
					self.transforms[fn] = (xf, inv)
				xf = xform_matrix(xf)
				affine_transform_vertices(pts, xf)
				affine_transform_vertices(pts, inverse)
			# add a half-voxel since volume positions are
			# considered to be at the center of their voxel
			from numpy import floor, zeros
			pts = floor(pts/spacing + 0.5).astype(int)
			for pt in pts:
				center = tuple(pt)
				gridData[center] = gridData.get(center, 0) + 1

		# generate volume
		self.status("Generating volume")
		axisData = zip(*tuple(gridData.keys()))
		minXyz = [min(ad) for ad in axisData]
		maxXyz = [max(ad) for ad in axisData]
		# allow for zero-padding on both ends
		dims = [maxXyz[axis] - minXyz[axis] + 3 for axis in range(3)]
		from numpy import zeros, transpose
		volume = zeros(dims, int)
		for index, val in gridData.items():
			adjIndex = tuple([index[i] - minXyz[i] + 1
							for i in range(3)])
			volume[adjIndex] = val
		from VolumeData import Array_Grid_Data
		gd = Array_Grid_Data(volume.transpose(),
					# the "cushion of zeros" means d-1...
					[(d-1) * spacing for d in minXyz],
					[spacing] * 3)
		if volumeName is None:
			volumeName = self.ensemble.name
		gd.name = volumeName

		# show volume
		self.status("Showing volume")
		import VolumeViewer
		dataRegion = VolumeViewer.volume_from_grid_data(gd)
		vd = VolumeViewer.volumedialog.volume_dialog(create=True)
		vd.message("Volume can be saved from File menu")

		self.status("Volume shown")
예제 #18
0
    def computeVolume(self, atoms, frame_ids, volumeName=None, spacing=0.5, radiiTreatment="ignored"):
        #function taken from Movie/gui.py and tweaked to compute volume based on an array of frame_ids
        from Matrix import xform_matrix
        gridData = {}
        from math import floor
        from numpy import array, float32, concatenate
        from _contour import affine_transform_vertices
        insideDeltas = {}
        include = {}
        sp2 = spacing * spacing
        for fn in frame_ids:
            cs = self.movie.findCoordSet(fn)
            if not cs:
                self.movie.status("Loading frame %d" % fn)
                self.movie._LoadFrame(int(fn), makeCurrent=False)
                cs = self.movie.findCoordSet(fn)

            self.movie.status("Processing frame %d" % fn)
            pts = array([a.coord(cs) for a in atoms], float32)
            if self.movie.holdingSteady:
                if bound is not None:
                    steadyPoints = array([a.coord(cs)
                        for a in steadyAtoms], float32)
                    closeIndices = find_close_points(
                        BOXES_METHOD, steadyPoints,
                        #otherPoints, bound)[1]
                        pts, bound)[1]
                    pts = pts[closeIndices]
                try:
                    xf, inv = self.movie.transforms[fn]
                except KeyError:
                    xf, inv = self.movie.steadyXform(cs=cs)
                    self.movie.transforms[fn] = (xf, inv)
                xf = xform_matrix(xf)
                affine_transform_vertices(pts, xf)
                affine_transform_vertices(pts, inverse)
            if radiiTreatment != "ignored":
                ptArrays = [pts]
                for pt, radius in zip(pts, [a.radius for a in atoms]):
                    if radius not in insideDeltas:
                        mul = 1
                        deltas = []
                        rad2 = radius * radius
                        while mul * spacing <= radius:
                            for dx in range(-mul, mul+1):
                                for dy in range(-mul, mul+1):
                                    for dz in range(-mul, mul+1):
                                        if radiiTreatment == "uniform" \
                                        and min(dx, dy, dz) > -mul and max(dx, dy, dz) < mul:
                                            continue
                                        key = tuple(sorted([abs(dx), abs(dy), abs(dz)]))
                                        if key not in include.setdefault(radius, {}):
                                            include[radius][key] = (dx*dx + dy*dy + dz*dz
                                                    ) * sp2 <= rad2
                                        if include[radius][key]:
                                            deltas.append([d*spacing for d in (dx,dy,dz)])
                            mul += 1
                        insideDeltas[radius] = array(deltas)
                        if len(deltas) < 10:
                            print deltas
                    if insideDeltas[radius].size > 0:
                        ptArrays.append(pt + insideDeltas[radius])
                pts = concatenate(ptArrays)
            # add a half-voxel since volume positions are
            # considered to be at the center of their voxel
            from numpy import floor, zeros
            pts = floor(pts/spacing + 0.5).astype(int)
            for pt in pts:
                center = tuple(pt)
                gridData[center] = gridData.get(center, 0) + 1

        # generate volume
        self.movie.status("Generating volume")
        axisData = zip(*tuple(gridData.keys()))
        minXyz = [min(ad) for ad in axisData]
        maxXyz = [max(ad) for ad in axisData]
        # allow for zero-padding on both ends
        dims = [maxXyz[axis] - minXyz[axis] + 3 for axis in range(3)]
        from numpy import zeros, transpose
        volume = zeros(dims, int)
        for index, val in gridData.items():
            adjIndex = tuple([index[i] - minXyz[i] + 1
                            for i in range(3)])
            volume[adjIndex] = val
        from VolumeData import Array_Grid_Data
        gd = Array_Grid_Data(volume.transpose(),
                    # the "cushion of zeros" means d-1...
                    [(d-1) * spacing for d in minXyz],
                    [spacing] * 3)
        if volumeName is None:
            volumeName = self.movie.ensemble.name
        gd.name = volumeName

        # show volume
        self.movie.status("Showing volume")
        import VolumeViewer
        dataRegion = VolumeViewer.volume_from_grid_data(gd)
        vd = VolumeViewer.volumedialog.volume_dialog(create=True)
        vd.message("Volume can be saved from File menu")
        self.movie.status("Volume shown")