def data_show_cb(self): """data_show_cb() - callback for show button Displays the data item on menu, using Volume Viewer. """ # find current data item on menu data_item = self.data_item_from_menu() if data_item == None: self.data_items_refresh() return # check if there is a data region associated with data item if data_item.region == None: from VolumeViewer import volume_from_grid_data volume_from_grid_data(data_item.data) data_item.update_region_name() self.update_data_menu_entry(data_item) # display data_item.region.show() self.data_menu_set(data_item) return
def add_data_sets_volume_viewer(self, grid_objects): """add_data_sets_volume_viewer(grid_objects) Add data sets corresponding to grid objects, to Volume Viewer. """ from VolumeViewer import volume_from_grid_data for g in grid_objects: volume_from_grid_data(g)
def make_molecule_map(atoms, resolution, step, pad, cutoff_range, sigma_factor, display_threshold, model_id, replace, show_dialog): atoms = tuple(atoms) grid, molecules = molecule_grid_data(atoms, resolution, step, pad, cutoff_range, sigma_factor) from chimera import openModels as om if replace: from VolumeViewer import volume_list vlist = [ v for v in volume_list() if getattr(v, 'molmap_atoms', None) == atoms ] om.close(vlist) from VolumeViewer import volume_from_grid_data v = volume_from_grid_data(grid, open_model=False, show_dialog=show_dialog) v.initialize_thresholds(mfrac=(display_threshold, 1), replace=True) v.show() v.molmap_atoms = tuple(atoms) # Remember atoms used to calculate volume v.molmap_parameters = (resolution, step, pad, cutoff_range, sigma_factor) if len(molecules) == 1 and model_id is None: om.add([v], sameAs=tuple(molecules)[0]) else: if model_id is None: model_id = (om.Default, om.Default) om.add([v], baseId=model_id[0], subid=model_id[1]) v.openState.xform = atoms[0].molecule.openState.xform return v
def split_volume_by_color_zone(v = None): if v is None: from VolumeViewer import active_volume v = active_volume() if v is None: return m = v.surface_model() import ColorZone if not ColorZone.coloring_zone(m): return points, colors, radius = ColorZone.zone_points_colors_and_distance(m) grids = split_zones_by_color(v, points, colors, radius) from VolumeViewer import volume_from_grid_data drlist = [volume_from_grid_data(g, show_data = False) for g in grids] n = len(v.surface_colors) for dr in drlist: dr.copy_settings_from(v, copy_region = False) dr.set_parameters(surface_colors = [dr.data.zone_color]*n) dr.show() v.unshow() return drlist
def cover_op(volumes, atomBox = None, pad = 5.0, box = None, x = None, y = None, z = None, fBox = None, fx = None, fy = None, fz = None, iBox = None, ix = None, iy = None, iz = None, step = 1, modelId = None): volumes = filter_volumes(volumes) check_number(pad, 'pad') if not atomBox is None and len(atomBox) == 0: raise CommandError, 'No atoms specified' box = parse_box(box, x, y, z, 'box', 'x', 'y', 'z') fBox = parse_box(fBox, fx, fy, fz, 'fBox', 'fx', 'fy', 'fz') iBox = parse_box(iBox, ix, iy, iz, 'iBox', 'ix', 'iy', 'iz') bc = len([b for b in (box, fBox, iBox, atomBox) if b]) if bc == 0: raise CommandError, 'Must specify box to cover' if bc > 1: raise CommandError, 'Specify covering box in one way' step = parse_step(step, require_3_tuple = True) modelId = parse_model_id(modelId) from VolumeViewer import volume, volume_from_grid_data for v in volumes: g = v.grid_data(subregion = 'all', step = step, mask_zone = False) ijk_min, ijk_max = cover_box_bounds(v, step, atomBox, pad, box, fBox, iBox) cg = volume.map_from_periodic_map(g, ijk_min, ijk_max) cv = volume_from_grid_data(cg, model_id = modelId) cv.copy_settings_from(v, copy_region = False) cv.show()
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')
def make_molecule_map(atoms, resolution, step, pad, cutoff_range, sigma_factor, display_threshold, model_id, replace, show_dialog): atoms = tuple(atoms) grid, molecules = molecule_grid_data(atoms, resolution, step, pad, cutoff_range, sigma_factor) from chimera import openModels as om if replace: from VolumeViewer import volume_list vlist = [v for v in volume_list() if getattr(v, 'molmap_atoms', None) == atoms] om.close(vlist) from VolumeViewer import volume_from_grid_data v = volume_from_grid_data(grid, open_model = False, show_dialog = show_dialog) v.initialize_thresholds(mfrac = (display_threshold, 1), replace = True) v.show() v.molmap_atoms = tuple(atoms) # Remember atoms used to calculate volume v.molmap_parameters = (resolution, step, pad, cutoff_range, sigma_factor) if len(molecules) == 1 and model_id is None: om.add([v], sameAs = tuple(molecules)[0]) else: if model_id is None: model_id = (om.Default, om.Default) om.add([v], baseId = model_id[0], subid = model_id[1]) v.openState.xform = atoms[0].molecule.openState.xform return v
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 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")
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 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 bounding_xray_map_symmetry(atoms, pad, volume): # Get atom positions. from _multiscale import get_atom_coordinates xyz = get_atom_coordinates(atoms, transformed = True) # Transform atom coordinates to volume ijk indices. from Matrix import multiply_matrices, xform_matrix tf = multiply_matrices(volume.data.xyz_to_ijk_transform, xform_matrix(volume.model_transform().inverse())) from _contour import affine_transform_vertices affine_transform_vertices(xyz, tf) ijk = xyz # Find integer bounds. from math import floor, ceil ijk_min = [int(floor(i-pad)) for i in ijk.min(axis=0)] ijk_max = [int(ceil(i+pad)) for i in ijk.max(axis=0)] #gather information about unit cell and symmetry ijk_cell_size = getattr(volume.data, 'unit_cell_size', volume.data.size) syms = volume.data.symmetries step = volume.data.step from VolumeFilter import cover cg = cover.map_covering_box(volume, ijk_min, ijk_max, ijk_cell_size, syms, step) from VolumeViewer import volume_from_grid_data v = volume_from_grid_data(cg, show_data = False) v.copy_settings_from(volume, copy_region = False) return v
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
def gaussian_convolve(volume, sdev, step = 1, subregion = None, modelId = None, task = None): gg = gaussian_grid(volume, sdev, step, subregion, task = task) from VolumeViewer import volume_from_grid_data gv = volume_from_grid_data(gg, show_data = False, model_id = modelId) gv.copy_settings_from(volume, copy_region = False) gv.show() volume.unshow() # Hide original map return gv
def median_filter(volume, bin_size = 3, iterations = 1, step = 1, subregion = None, modelId = None): mg = median_grid(volume, bin_size, iterations, step, subregion) from VolumeViewer import volume_from_grid_data mv = volume_from_grid_data(mg, show_data = False, model_id = modelId) mv.copy_settings_from(volume, copy_region = False) mv.show() volume.unshow() # Hide original map return mv
def add_operation(volumes, subregion, step, gv, gridSubregion, gridStep, boundingGrid, inPlace, scale, modelId): if scale is None: scale = [1] * len(volumes) if inPlace: rv = gv for i, v in enumerate(volumes): s = (scale[i] if v != rv else scale[i] - 1) rv.add_interpolated_values(v, subregion=subregion, step=step, scale=s) else: gr = gv.subregion(step=gridStep, subregion=gridSubregion) if boundingGrid: if same_grids(volumes, subregion, step, gv, gr): # Avoid extending grid due to round-off errors. r = gr else: corners = volume_corners(volumes, subregion, step, gv.model_transform()) r = gv.bounding_region(corners, step=gridStep, clamp=False) else: r = gr rg = gv.region_grid(r) if len(volumes) == 1: rg.name = volumes[0].name + ' resampled' elif scale[1] == 'minrms' or scale[1] < 0: rg.name = 'volume difference' else: rg.name = 'volume sum' from VolumeViewer import volume_from_grid_data rv = volume_from_grid_data(rg, model_id=modelId, show_data=False, show_dialog=False) rv.openState.xform = gv.openState.xform for i, v in enumerate(volumes): rv.add_interpolated_values(v, subregion=subregion, step=step, scale=scale[i]) rv.data.values_changed() if volumes: rv.copy_settings_from(volumes[0], copy_region=False, copy_xform=False) rv.show() for v in volumes: if not v is rv: v.unshow()
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
def add_operation(volumes, subregion, step, gv, gridSubregion, gridStep, boundingGrid, inPlace, scale, modelId): if scale is None: scale = [1]*len(volumes) if inPlace: rv = gv for i, v in enumerate(volumes): s = (scale[i] if v != rv else scale[i]-1) rv.add_interpolated_values(v, subregion = subregion, step = step, scale = s) else: gr = gv.subregion(step = gridStep, subregion = gridSubregion) if boundingGrid: if same_grids(volumes, subregion, step, gv, gr): # Avoid extending grid due to round-off errors. r = gr else: corners = volume_corners(volumes, subregion, step, gv.model_transform()) r = gv.bounding_region(corners, step = gridStep, clamp = False) else: r = gr rg = gv.region_grid(r) if len(volumes) == 1: rg.name = volumes[0].name + ' resampled' elif scale[1] == 'minrms' or scale[1] < 0: rg.name = 'volume difference' else: rg.name = 'volume sum' from VolumeViewer import volume_from_grid_data rv = volume_from_grid_data(rg, model_id = modelId, show_data = False, show_dialog = False) rv.openState.xform = gv.openState.xform for i,v in enumerate(volumes): rv.add_interpolated_values(v, subregion = subregion, step = step, scale = scale[i]) rv.data.values_changed() if volumes: rv.copy_settings_from(volumes[0], copy_region = False, copy_xform = False) rv.show() for v in volumes: if not v is rv: v.unshow()
def cover_op(volumes, atomBox=None, pad=5.0, box=None, x=None, y=None, z=None, fBox=None, fx=None, fy=None, fz=None, iBox=None, ix=None, iy=None, iz=None, step=1, modelId=None): volumes = filter_volumes(volumes) check_number(pad, 'pad') if not atomBox is None and len(atomBox) == 0: raise CommandError, 'No atoms specified' box = parse_box(box, x, y, z, 'box', 'x', 'y', 'z') fBox = parse_box(fBox, fx, fy, fz, 'fBox', 'fx', 'fy', 'fz') iBox = parse_box(iBox, ix, iy, iz, 'iBox', 'ix', 'iy', 'iz') bc = len([b for b in (box, fBox, iBox, atomBox) if b]) if bc == 0: raise CommandError, 'Must specify box to cover' if bc > 1: raise CommandError, 'Specify covering box in one way' step = parse_step(step, require_3_tuple=True) modelId = parse_model_id(modelId) from VolumeViewer import volume, volume_from_grid_data for v in volumes: g = v.grid_data(subregion='all', step=step, mask_zone=False) ijk_min, ijk_max = cover_box_bounds(v, step, atomBox, pad, box, fBox, iBox) cg = volume.map_from_periodic_map(g, ijk_min, ijk_max) cv = volume_from_grid_data(cg, model_id=modelId) cv.copy_settings_from(v, copy_region=False) cv.show()
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 boxes(volume, atoms, size=0, use_atom_size=False, step=None, subregion=None, base_model_id=None): vlist = [] vxfinv = volume.openState.xform.inverse() ijk_rmin, ijk_rmax = volume.ijk_bounds(step, subregion, integer=True) for i, a in enumerate(atoms): center = vxfinv.apply(a.xformCoord()).data() r = 0.5 * size if use_atom_size: r += a.radius ijk_min, ijk_max, ijk_step = volume.bounding_region([center], r, step) ijk_min = [max(s, t) for s, t in zip(ijk_min, ijk_rmin)] ijk_max = [min(s, t) for s, t in zip(ijk_max, ijk_rmax)] region = (ijk_min, ijk_max, ijk_step) from VolumeViewer.volume import is_empty_region if is_empty_region(region): continue from VolumeData import Grid_Subregion g = Grid_Subregion(volume.data, *region) g.name = 'box' if base_model_id is None: mid = None else: mid = base_model_id[0] + i from VolumeViewer import volume_from_grid_data v = volume_from_grid_data(g, model_id=mid, show_data=False, show_dialog=False) v.copy_settings_from(volume, copy_region=False, copy_active=False, copy_zone=False) v.show() vlist.append(v) return vlist
def show_in_volume_viewer(self): data_seq = list(self.data_sets) data_seq.sort(lambda a,b: cmp(a.time, b.time)) from VolumeViewer import volume_from_grid_data data_regions = [volume_from_grid_data(g, show_data = False) for g in data_seq] self.data_regions = list(data_regions) # Add callbacks to detect when volume data sets are closed. import chimera for v in data_regions: chimera.addModelClosedCallback(v, self.volume_closed) if data_regions: dr = data_regions[0] from VolumeViewer import set_active_volume set_active_volume(dr) dr.initialize_thresholds() dr.show()
def display_rawiv(path): """display_rawiv(path) - open and display a RawIV file. Input: path input file Output: grid_object VolumeData grid data object data_region VolumeViewer data region Reads and displays the RawIV data in the file specified by path and returns a Chimera grid data object and a data region (see the Volume Data and Volume Viewer modules in Chimera). """ grid_object = open(path) from VolumeViewer import volume_from_grid_data data_region = volume_from_grid_data(grid_object) return grid_object, data_region
def show_in_volume_viewer(self): data_seq = list(self.data_sets) data_seq.sort(lambda a, b: cmp(a.time, b.time)) from VolumeViewer import volume_from_grid_data data_regions = [ volume_from_grid_data(g, show_data=False) for g in data_seq ] self.data_regions = list(data_regions) # Add callbacks to detect when volume data sets are closed. import chimera for v in data_regions: chimera.addModelClosedCallback(v, self.volume_closed) if data_regions: dr = data_regions[0] from VolumeViewer import set_active_volume set_active_volume(dr) dr.initialize_thresholds() dr.show()
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)
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()
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)
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
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