def close_packing_matrices(tflist, ref_point, center, a, b, c, alpha, beta, gamma): u2r = unit_cell_to_xyz_matrix(a, b, c, alpha, beta, gamma) from Matrix import invert_matrix r2u = invert_matrix(u2r) stflist = [] from Matrix import apply_matrix, translation_matrix, multiply_matrices from numpy import array, subtract, add for tf in tflist: # shift = u2r * -map(int, r2u * (tf * center - center) + (.5,.5,.5)) ntf = array(tf) tfc = apply_matrix(ntf, ref_point) csep = subtract(tfc, center) ucsep = apply_matrix(r2u, csep) import math ushift = map(math.floor, add(ucsep, (.5,.5,.5))) shift = apply_matrix(u2r, ushift) neg_shift = map(lambda x: -x, shift) tfshift = translation_matrix(neg_shift) stf = multiply_matrices(tfshift, ntf) stflist.append(stf) return stflist
def close_packing_matrices(tflist, ref_point, center, a, b, c, alpha, beta, gamma): u2r = unit_cell_to_xyz_matrix(a, b, c, alpha, beta, gamma) from Matrix import invert_matrix r2u = invert_matrix(u2r) stflist = [] from Matrix import apply_matrix, translation_matrix, multiply_matrices from numpy import array, subtract, add for tf in tflist: # shift = u2r * -map(int, r2u * (tf * center - center) + (.5,.5,.5)) ntf = array(tf) tfc = apply_matrix(ntf, ref_point) csep = subtract(tfc, center) ucsep = apply_matrix(r2u, csep) import math ushift = map(math.floor, add(ucsep, (.5, .5, .5))) shift = apply_matrix(u2r, ushift) neg_shift = map(lambda x: -x, shift) tfshift = translation_matrix(neg_shift) stf = multiply_matrices(tfshift, ntf) stflist.append(stf) return stflist
def line_perpendicular_to_screen(window_x, window_y, transform): xyz_near, xyz_far = clip_plane_points(window_x, window_y) from Matrix import apply_matrix xyz_near = apply_matrix(transform, xyz_near) xyz_far = apply_matrix(transform, xyz_far) dir = map(lambda a, b: a - b, xyz_far, xyz_near) line = (xyz_near, dir) return line
def line_perpendicular_to_screen(window_x, window_y, transform): xyz_near, xyz_far = clip_plane_points(window_x, window_y) from Matrix import apply_matrix xyz_near = apply_matrix(transform, xyz_near) xyz_far = apply_matrix(transform, xyz_far) dir = map(lambda a,b: a-b, xyz_far, xyz_near) line = (xyz_near, dir) return line
def chain_center(chain): xyz = chain.lan_chain.source_atom_xyz() sc = center(xyz) from Matrix import apply_matrix, xform_matrix c = apply_matrix(xform_matrix(chain.xform), sc) return c
def show_position(self): ppos = self.phantom_device.cursor_position_mm() cpos = self.phantom_device.cursor_position() for a in range(3): self.phantom_position_labels[a]['text'] = float_format(ppos[a], 3) self.chimera_position_labels[a]['text'] = float_format(cpos[a], 3) gf = self.gradient_force v = self.data_region() if gf and v: xf = v.model_transform() vpos = xf.inverse().apply(cpos) from Matrix import apply_matrix ipos = apply_matrix(gf.xyz_to_grid_index, cpos.data()) grad = gf.gradient(cpos) grad = xf.inverse().apply(grad) # Transform global to volume coords force = gf.force(cpos) force = xf.inverse().apply(force) # Transform global to volume coords for a in range(3): self.volume_position_labels[a]['text'] = float_format(vpos[a], 3) self.volume_index_labels[a]['text'] = float_format(ipos[a], 3) self.gradient_labels[a]['text'] = float_format(grad[a], 3) self.force_labels[a]['text'] = float_format(force[a], 3) data_value = gf.data_value(cpos) self.data_value_label['text'] = float_format(data_value, 3) else: labels = (self.volume_position_labels + self.volume_index_labels + self.gradient_labels + self.force_labels + [self.data_value_label]) for label in labels: label['text'] = ''
def show_position(self): ppos = self.phantom_device.cursor_position_mm() cpos = self.phantom_device.cursor_position() for a in range(3): self.phantom_position_labels[a]['text'] = float_format(ppos[a], 3) self.chimera_position_labels[a]['text'] = float_format(cpos[a], 3) gf = self.gradient_force v = self.data_region() if gf and v: xf = v.model_transform() vpos = xf.inverse().apply(cpos) from Matrix import apply_matrix ipos = apply_matrix(gf.xyz_to_grid_index, cpos.data()) grad = gf.gradient(cpos) grad = xf.inverse().apply( grad) # Transform global to volume coords force = gf.force(cpos) force = xf.inverse().apply( force) # Transform global to volume coords for a in range(3): self.volume_position_labels[a]['text'] = float_format( vpos[a], 3) self.volume_index_labels[a]['text'] = float_format(ipos[a], 3) self.gradient_labels[a]['text'] = float_format(grad[a], 3) self.force_labels[a]['text'] = float_format(force[a], 3) data_value = gf.data_value(cpos) self.data_value_label['text'] = float_format(data_value, 3) else: labels = (self.volume_position_labels + self.volume_index_labels + self.gradient_labels + self.force_labels + [self.data_value_label]) for label in labels: label['text'] = ''
def shift_and_angle(tf, center): from Matrix import chimera_xform, apply_matrix moved_center = apply_matrix(tf, center) shift_vector = map(lambda a, b: a - b, moved_center, center) shift = norm(shift_vector) axis, angle = chimera_xform(tf).getRotation() return shift, angle
def transformed_bounding_box(box, tf): (x0,y0,z0), (x1,y1,z1) = box corners = ((x0,y0,z0), (x0,y0,z1), (x0,y1,z0), (x0,y1,z1), (x1,y0,z0), (x1,y0,z1), (x1,y1,z0), (x1,y1,z1)) from Matrix import apply_matrix tf_corners = map(lambda c: apply_matrix(tf, c), corners) tf_box = bounding_box(tf_corners) return tf_box
def transformed_bounding_box(box, tf): (x0, y0, z0), (x1, y1, z1) = box corners = ((x0, y0, z0), (x0, y0, z1), (x0, y1, z0), (x0, y1, z1), (x1, y0, z0), (x1, y0, z1), (x1, y1, z0), (x1, y1, z1)) from Matrix import apply_matrix tf_corners = map(lambda c: apply_matrix(tf, c), corners) tf_box = bounding_box(tf_corners) return tf_box
def transform_plane(plane, transform): from Matrix import invert_matrix, transpose_matrix from Matrix import apply_matrix_without_translation, apply_matrix inv_tf = invert_matrix(transform) inv_tf_transpose = transpose_matrix(inv_tf) normal, offset = plane n = apply_matrix_without_translation(inv_tf_transpose, normal) o = offset - inner_product(normal, apply_matrix(inv_tf, (0, 0, 0))) return (n, o)
def transform_plane(plane, transform): from Matrix import invert_matrix, transpose_matrix from Matrix import apply_matrix_without_translation, apply_matrix inv_tf = invert_matrix(transform) inv_tf_transpose = transpose_matrix(inv_tf) normal, offset = plane n = apply_matrix_without_translation(inv_tf_transpose, normal) o = offset - inner_product(normal, apply_matrix(inv_tf, (0,0,0))) return (n, o)
def maximum_ijk_motion(points, xyz_to_ijk_transform, move_tf): from Matrix import multiply_matrices, apply_matrix, maximum_norm ijk_moved_tf = multiply_matrices(xyz_to_ijk_transform, move_tf) from numpy import subtract diff_tf = subtract(ijk_moved_tf, xyz_to_ijk_transform) ijk_diff = apply_matrix(diff_tf, points) d = maximum_norm(ijk_diff) return d
def close_center_transforms(mol, csys, tflist, rdist): have_box, box = mol.bbox() if not have_box: return [] c = mol.openState.xform.apply(box.center()) # center cref = csys.openState.xform.inverse().apply(c).data() # reference coords from Matrix import distance, apply_matrix rtflist = [tf for tf in tflist if distance(cref, apply_matrix(tf, cref)) < rdist] return rtflist
def volume_segment(volume, pointer_x, pointer_y): xyz_in = xyz_out = None from VolumeViewer import selectregion box, tf, xform = selectregion.box_transform_and_xform(volume) shown = (box != None) if shown: transform = selectregion.box_to_eye_transform(tf, xform) mlist = filter(lambda m: m.display, volume.models()) if mlist: clipping_model = mlist[0] else: clipping_model = None ijk_in, ijk_out = box_intercepts(pointer_x, pointer_y, transform, box, clipping_model) if ijk_in != None and ijk_out != None: from Matrix import apply_matrix xyz_in = apply_matrix(tf, ijk_in) xyz_out = apply_matrix(tf, ijk_out) return xyz_in, xyz_out, shown
def close_center_transforms(mol, csys, tflist, rdist): have_box, box = mol.bbox() if not have_box: return [] c = mol.openState.xform.apply(box.center()) # center cref = csys.openState.xform.inverse().apply(c).data() # reference coords from Matrix import distance, apply_matrix rtflist = [ tf for tf in tflist if distance(cref, apply_matrix(tf, cref)) < rdist ] return rtflist
def ijk_box_bounds(self, xform): bm = self.box_model if bm.box is None: return None, None corners = box_corners(bm.box) from Matrix import multiply_matrices, apply_matrix tf = multiply_matrices( eye_to_box_transform(bm.box_transform, xform), box_to_eye_transform(bm.box_transform, bm.xform())) ijk_box = bounding_box([apply_matrix(tf, c) for c in corners]) return ijk_box
def view_distance(self): xf = self.xform() if xf == None or self.box == None: d = near_clip_plane_distance() else: tf = box_to_eye_transform(self.box_transform, xf) from Matrix import apply_matrix center = apply_matrix(tf, box_center(self.box)) z_box = center[2] eye_number = 0 z_eye = chimera.viewer.camera.eyePos(eye_number)[2] z_range = z_eye - z_box d = max(z_range, near_clip_plane_distance()) return d
def apply_inverse_matrix(tf, *xyz_list): import chimera if isinstance(tf, chimera.Xform): tf = xform_matrix(tf) inv_tf = invert_matrix(tf) inv_tf_xyz_list = [] for xyz in xyz_list: inv_tf_xyz = apply_matrix(inv_tf, xyz) inv_tf_xyz_list.append(inv_tf_xyz) if len(xyz_list) == 1: return inv_tf_xyz_list[0] return inv_tf_xyz_list
def angle_step(axis, points, center, xyz_to_ijk_transform, ijk_step_size): from numpy import subtract, array xyz_offset = subtract(points, center) from Matrix import cross_product_transform, multiply_matrices, apply_matrix, maximum_norm cp_tf = cross_product_transform(axis) tf = array(multiply_matrices(xyz_to_ijk_transform, cp_tf)) tf[:,3] = 0 # zero translation av_ijk = apply_matrix(tf, xyz_offset) av = maximum_norm(av_ijk) if av > 0: from math import pi angle = (ijk_step_size / av) * 180.0/pi else: angle = 0 return angle
def copy_slab(depth, depth2, mijk_to_dijk, vol, mvol, dlimit): ksize, jsize, isize = mvol.shape djsize, disize = depth.shape from Matrix import apply_matrix for k in range(ksize): for j in range(jsize): for i in range(isize): di, dj, dk = apply_matrix(mijk_to_dijk, (i, j, k)) if di >= 0 and di < disize - 1 and dj >= 0 and dj < djsize - 1: # Interpolate depths, nearest neighbor # TODO: use linear interpolation. di = int(di + 0.5) dj = int(dj + 0.5) d1 = depth[dj, di] d2 = depth2[dj, di] if dk >= d1 and dk <= d2 and d1 <= dlimit and d2 <= dlimit: mvol[k, j, i] = vol[k, j, i]
def copy_slab(depth, depth2, mijk_to_dijk, vol, mvol, dlimit): ksize, jsize, isize = mvol.shape djsize, disize = depth.shape from Matrix import apply_matrix for k in range(ksize): for j in range(jsize): for i in range(isize): di,dj,dk = apply_matrix(mijk_to_dijk, (i,j,k)) if di >= 0 and di < disize-1 and dj >= 0 and dj < djsize-1: # Interpolate depths, nearest neighbor # TODO: use linear interpolation. di = int(di + 0.5) dj = int(dj + 0.5) d1 = depth[dj,di] d2 = depth2[dj,di] if dk >= d1 and dk <= d2 and d1 <= dlimit and d2 <= dlimit: mvol[k,j,i] = vol[k,j,i]
def report_distance(xyz1, xyz2, from_name, to_name, surf, color): i1, i2, d = closest_approach(xyz1, xyz2) msg = 'minimum distance from %s to %s = %.5g' % (from_name, to_name, d) from chimera import replyobj replyobj.status(msg) replyobj.info(msg + '\n') if surf: from Matrix import apply_matrix, xform_matrix tf = xform_matrix(surf.openState.xform.inverse()) v = apply_matrix(tf, (xyz1[i1], xyz2[i2])) t = [(0, 1, 0)] p = surf.addPiece(v, t, color) p.displayStyle = p.Mesh p.useLighting = False p.lineThickness = 3
def transform_schematic(xform, center, from_rgba, to_rgba): corners = transform_square(xform, center) if corners is None: return None # No rotation. import _surface sm = _surface.SurfaceModel() varray = corners tarray = ((0,1,2),(0,2,3),(0,1,5),(0,5,4),(1,2,6),(1,6,5), (2,3,7),(2,7,6),(3,0,4),(3,4,7),(4,5,6),(4,6,7)) g1 = sm.addPiece(varray, tarray, from_rgba) from Matrix import xform_matrix, apply_matrix tf = xform_matrix(xform) corners2 = [apply_matrix(tf, p) for p in corners] varray2 = corners2 g2 = sm.addPiece(varray2, tarray, to_rgba) return sm
def transform_schematic(xform, center, from_rgba, to_rgba): corners = transform_square(xform, center) if corners is None: return None # No rotation. import _surface sm = _surface.SurfaceModel() varray = corners tarray = ((0, 1, 2), (0, 2, 3), (0, 1, 5), (0, 5, 4), (1, 2, 6), (1, 6, 5), (2, 3, 7), (2, 7, 6), (3, 0, 4), (3, 4, 7), (4, 5, 6), (4, 6, 7)) g1 = sm.addPiece(varray, tarray, from_rgba) from Matrix import xform_matrix, apply_matrix tf = xform_matrix(xform) corners2 = [apply_matrix(tf, p) for p in corners] varray2 = corners2 g2 = sm.addPiece(varray2, tarray, to_rgba) return sm
def icosahedron_geometry(orientation = '2n5'): a23, a25, a35 = icosahedron_angles() a = 2*a25 # Angle spanned by edge from center # 5-fold symmetry axis along z from math import cos, sin, pi c5 = cos(2*pi/5) s5 = sin(2*pi/5) tf5 = ((c5, -s5, 0, 0), (s5, c5, 0, 0), (0, 0, 1, 0)) # 2-fold symmetry axis along x tf2 = ((1, 0, 0, 0), (0, -1, 0, 0), (0, 0, -1, 0)) p = (0, 0, 1) p50 = (0, sin(a), cos(a)) from Matrix import apply_matrix p51 = apply_matrix(tf5, p50) p52= apply_matrix(tf5, p51) p53 = apply_matrix(tf5, p52) p54 = apply_matrix(tf5, p53) vertices = [p, p50, p51, p52, p53, p54] vertices.extend([apply_matrix(tf2, q) for q in vertices]) if orientation != '2n5': tf = coordinate_system_transform('2n5', orientation) vertices = [apply_matrix(tf, p) for p in vertices] # # Vertex numbering # # Top 1 Bottom # 2 5 9 10 # 0 6 # 3 4 8 11 # 7 # 20 triangles composing icosahedron. # triangles = ((0,1,2), (0,2,3), (0,3,4), (0,4,5), (0,5,1), (6,7,8), (6,8,9), (6,9,10), (6,10,11), (6,11,7), (1,9,2), (2,9,8), (2,8,3), (3,8,7), (3,7,4), (4,7,11), (4,11,5), (5,11,10), (5,10,1), (1,10,9)) return vertices, triangles
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
def create_asymmetric_unit_markers(marker_set, asu_list, asu_center, identity_smtry_index, rgba_ncs, rgba_uc, rgba_ouc, radius_ncs, radius_copies): markers = {} from Matrix import apply_matrix for asu in asu_list: c = apply_matrix(asu.transform, asu_center) if asu.unit_cell_index != (0, 0, 0): color = rgba_ouc r = radius_copies elif asu.smtry_index == identity_smtry_index: color = rgba_ncs r = radius_ncs else: color = rgba_uc r = radius_copies m = marker_set.place_marker(c, color, r) m.atom.name = ('n%d s%d %d %d %d' % ( (asu.ncs_index, asu.smtry_index) + asu.unit_cell_index)) markers[(asu.ncs_index, asu.smtry_index, asu.unit_cell_index)] = m return markers
def create_asymmetric_unit_markers(marker_set, asu_list, asu_center, identity_smtry_index, rgba_ncs, rgba_uc, rgba_ouc, radius_ncs, radius_copies): markers = {} from Matrix import apply_matrix for asu in asu_list: c = apply_matrix(asu.transform, asu_center) if asu.unit_cell_index != (0,0,0): color = rgba_ouc r = radius_copies elif asu.smtry_index == identity_smtry_index: color = rgba_ncs r = radius_ncs else: color = rgba_uc r = radius_copies m = marker_set.place_marker(c, color, r) m.atom.name = ('n%d s%d %d %d %d' % ((asu.ncs_index, asu.smtry_index) + asu.unit_cell_index)) markers[(asu.ncs_index, asu.smtry_index, asu.unit_cell_index)] = m return markers
def transform_box_corners(box, transform): corners = box_corners(box) from Matrix import apply_matrix tcorners = map(lambda p: apply_matrix(transform, p), corners) return tcorners
def map_triangles(tmap, triangles): from Matrix import apply_matrix tri = map(lambda t: map(lambda v: apply_matrix(tmap, v), t), triangles) return tri
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