def step_to_maximum(points, point_weights, data_array, xyz_to_ijk_transform, steps, ijk_step_size, optimize_translation, optimize_rotation, rotation_center, metric): step_types = [] if optimize_translation: step_types.append(translation_step) if optimize_rotation: step_types.append(rotation_step) from Matrix import identity_matrix, multiply_matrices move_tf = identity_matrix() if step_types: for step in range(steps): calculate_step = step_types[step % len(step_types)] xyz_to_ijk_tf = multiply_matrices(xyz_to_ijk_transform, move_tf) # amv, npts = average_map_value(points, xyz_to_ijk_tf, data_array) # print 'average map value = %.3g for %d atoms' % (amv, npts) step_tf = calculate_step(points, point_weights, rotation_center, data_array, xyz_to_ijk_tf, ijk_step_size, metric) move_tf = multiply_matrices(step_tf, move_tf) # mm = maximum_ijk_motion(points, xyz_to_ijk_transform, move_tf) # print 'ijk motion for step', step, ' = ', mm return move_tf
def nearby_boxes(box, crystal): from Matrix import multiply_matrices, invert_matrix act = basis_coordinate_transform(crystal.axes) isi = crystal.identity_smtry_index box2_cache = {} plist = [] for ncs1index, ncs1 in enumerate(crystal.ncs_matrices): ncs1_inv = invert_matrix(ncs1) box1 = transformed_bounding_box(box, multiply_matrices(act, ncs1)) asu1 = NCS_Asymmetric_Unit(ncs1index, isi, (0,0,0), ncs1) for ncs2index, ncs2 in enumerate(crystal.ncs_matrices): for symindex, sym in enumerate(crystal.smtry_matrices): identity_sym = (symindex == isi) if (ncs2index, symindex) in box2_cache: sym_ncs2, box2 = box2_cache[(ncs2index, symindex)] else: sym_ncs2 = multiply_matrices(sym, ncs2) box2_tf = multiply_matrices(act, sym_ncs2) box2 = transformed_bounding_box(box, box2_tf) box2_cache[(ncs2index, symindex)] = (sym_ncs2, box2) tlist = overlapping_translations(box1, box2, crystal.axes) for t, ucijk in tlist: if (identity_sym and ucijk == (0,0,0) and ncs1index >= ncs2index): continue # Include only 1 copy of pair trans_sym_ncs2 = translate_matrix(t, sym_ncs2) asu2 = NCS_Asymmetric_Unit(ncs2index, symindex, ucijk, trans_sym_ncs2) plist.append((asu1, asu2)) return plist
def nearby_boxes(box, crystal): from Matrix import multiply_matrices, invert_matrix act = basis_coordinate_transform(crystal.axes) isi = crystal.identity_smtry_index box2_cache = {} plist = [] for ncs1index, ncs1 in enumerate(crystal.ncs_matrices): ncs1_inv = invert_matrix(ncs1) box1 = transformed_bounding_box(box, multiply_matrices(act, ncs1)) asu1 = NCS_Asymmetric_Unit(ncs1index, isi, (0, 0, 0), ncs1) for ncs2index, ncs2 in enumerate(crystal.ncs_matrices): for symindex, sym in enumerate(crystal.smtry_matrices): identity_sym = (symindex == isi) if (ncs2index, symindex) in box2_cache: sym_ncs2, box2 = box2_cache[(ncs2index, symindex)] else: sym_ncs2 = multiply_matrices(sym, ncs2) box2_tf = multiply_matrices(act, sym_ncs2) box2 = transformed_bounding_box(box, box2_tf) box2_cache[(ncs2index, symindex)] = (sym_ncs2, box2) tlist = overlapping_translations(box1, box2, crystal.axes) for t, ucijk in tlist: if (identity_sym and ucijk == (0, 0, 0) and ncs1index >= ncs2index): continue # Include only 1 copy of pair trans_sym_ncs2 = translate_matrix(t, sym_ncs2) asu2 = NCS_Asymmetric_Unit(ncs2index, symindex, ucijk, trans_sym_ncs2) plist.append((asu1, asu2)) return plist
def locate_maximum(points, point_weights, data_array, xyz_to_ijk_transform, max_steps, ijk_step_size_min, ijk_step_size_max, optimize_translation, optimize_rotation, metric, request_stop_cb): segment_steps = 4 cut_step_size_threshold = .5 step_cut_factor = .5 ijk_step_size = ijk_step_size_max from Matrix import identity_matrix, multiply_matrices from Matrix import shift_and_angle, axis_center_angle_shift move_tf = identity_matrix() from numpy import sum rotation_center = sum(points, axis=0) / len(points) step = 0 while step < max_steps and ijk_step_size > ijk_step_size_min: xyz_to_ijk_tf = multiply_matrices(xyz_to_ijk_transform, move_tf) seg_tf = step_to_maximum(points, point_weights, data_array, xyz_to_ijk_tf, segment_steps, ijk_step_size, optimize_translation, optimize_rotation, rotation_center, metric) step += segment_steps mm = maximum_ijk_motion(points, xyz_to_ijk_tf, seg_tf) if mm < cut_step_size_threshold * segment_steps * ijk_step_size: ijk_step_size *= step_cut_factor move_tf = multiply_matrices(seg_tf, move_tf) if request_stop_cb: shift, angle = shift_and_angle(move_tf, rotation_center) if request_stop_cb('After %d steps: shift %.3g, rotation %.3g degrees' % (step, shift, angle)): break # Record statistics of optimization. shift, angle = shift_and_angle(move_tf, rotation_center) axis, axis_point, angle, axis_shift = axis_center_angle_shift(move_tf) xyz_to_ijk_tf = multiply_matrices(xyz_to_ijk_transform, move_tf) stats = {'shift': shift, 'axis': axis, 'axis point': axis_point, 'angle': angle, 'axis shift': axis_shift, 'steps': step, 'points': len(points), 'transform': move_tf} if point_weights is None: amv, npts = average_map_value(points, xyz_to_ijk_tf, data_array) stats['average map value'] = amv stats['points in map'] = npts # Exludes out of bounds points else: from VolumeData import interpolate_volume_data map_values, outside = interpolate_volume_data(points, xyz_to_ijk_tf, data_array) olap, cor, corm = overlap_and_correlation(point_weights, map_values) stats['overlap'] = olap stats['correlation'] = cor stats['correlation about mean'] = corm return move_tf, stats
def multiply_matrices(*mlist): if len(mlist) == 2: m1, m2 = mlist p = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] for r in range(3): for c in range(4): p[r][c] = m1[r][0] * m2[0][c] + m1[r][1] * m2[1][c] + m1[r][ 2] * m2[2][c] p[r][3] += m1[r][3] p = tuple(map(tuple, p)) else: p = multiply_matrices(*mlist[1:]) p = multiply_matrices(mlist[0], p) return p
def report_correlations_with_rotation(v1, v2, aboveThreshold, axis, center, angleRange, plot): from chimera import Vector, Point, replyobj # Convert axis and center to v1 local coordinates so transformation # is still valid if user rotates entire scene. xf = v1.openState.xform.inverse() axis = xf.apply(Vector(*axis)).data() center = xf.apply(Point(*center)).data() import FitMap, Matrix replyobj.info('Correlation between %s and %s\n' % (v1.name, v2.name) + 'Rotation\tCorrelation\n') a0, a1, astep = angleRange angle = a0 clist = [] from Matrix import multiply_matrices, xform_matrix, rotation_transform, chimera_xform while angle < a1: tf = multiply_matrices(xform_matrix(v1.openState.xform), rotation_transform(axis, angle, center), xform_matrix(v1.openState.xform.inverse())) xf = chimera_xform(tf) olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold, xf) replyobj.status('angle = %.4g, correlation = %.4g\n' % (angle, cor)) replyobj.info('%.4g\t%.4g\n' % (angle, cor)) clist.append((angle,cor)) angle += astep if plot: angles = [a for a,c in clist] corr = [c for a,c in clist] plot_correlation(angles, corr, v1, v2, axis, center)
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 unique_asymmetric_unit_pairs(plist, angle_tolerance, shift_tolerance): from bins import Binned_Transforms b = Binned_Transforms(angle_tolerance, shift_tolerance) from Matrix import invert_matrix, multiply_matrices uplist = [] tf1_inverse_cache = {} equiv_asu_pairs = {} for asu1, asu2 in plist: tf1_index = asu1.ncs_index if tf1_index in tf1_inverse_cache: tf1_inv = tf1_inverse_cache[tf1_index] else: tf1_inv = invert_matrix(asu1.transform) tf1_inverse_cache[tf1_index] = tf1_inv rel = multiply_matrices(tf1_inv, asu2.transform) close = b.close_transforms(rel) if close: equiv_asu_pairs[close[0]].append((asu1, asu2)) # duplicate else: b.add_transform(rel) equiv_asu_pairs[rel] = [(asu1, asu2)] uplist.append(equiv_asu_pairs[rel]) return uplist
def report_correlations_with_rotation(v1, v2, aboveThreshold, axis, center, angleRange, plot): from chimera import Vector, Point, replyobj # Convert axis and center to v1 local coordinates so transformation # is still valid if user rotates entire scene. xf = v1.openState.xform.inverse() axis = xf.apply(Vector(*axis)).data() center = xf.apply(Point(*center)).data() import FitMap, Matrix replyobj.info('Correlation between %s and %s\n' % (v1.name, v2.name) + 'Rotation\tCorrelation\n') a0, a1, astep = angleRange angle = a0 clist = [] from Matrix import multiply_matrices, xform_matrix, rotation_transform, chimera_xform while angle < a1: tf = multiply_matrices(xform_matrix(v1.openState.xform), rotation_transform(axis, angle, center), xform_matrix(v1.openState.xform.inverse())) xf = chimera_xform(tf) olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold, xf) replyobj.status('angle = %.4g, correlation = %.4g\n' % (angle, cor)) replyobj.info('%.4g\t%.4g\n' % (angle, cor)) clist.append((angle, cor)) angle += astep if plot: angles = [a for a, c in clist] corr = [c for a, c in clist] plot_correlation(angles, corr, v1, v2, axis, center)
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_transforms(self, tf): a = rotation_angle(tf) # In range 0 to pi x,y,z = tf[0][3], tf[1][3], tf[2][3] c = (a,x,y,z) clist = self.bins.close_objects(c, self.spacing) if len(clist) == 0: return [] close = [] from Matrix import invert_matrix, multiply_matrices itf = invert_matrix(tf) for ctf in clist: dtf = multiply_matrices(ctf, itf) x,y,z = dtf[0][3], dtf[1][3], dtf[2][3] if (abs(x) < self.translation and abs(y) < self.translation and abs(z) < self.translation): a = rotation_angle(dtf) from math import pi if a < self.angle: close.append(ctf) return close
def clicked_mask_region(segmentation, pointer_x, pointer_y): s = segmentation if not s.display: return None if s.mask is None: print 'mouse down: no current segmentation mask' return None mk, mj, mi = s.mask.shape box = ((0, 0, 0), (mi, mj, mk)) from Matrix import xform_matrix, multiply_matrices ijk_to_eye = multiply_matrices(xform_matrix(s.openState.xform), s.point_transform()) from VolumeViewer.slice import box_intercepts, array_slice_values ijk_in, ijk_out = box_intercepts(pointer_x, pointer_y, ijk_to_eye, box, s) if ijk_in is None or ijk_out is None: print 'mouse down: no intercept with mask' return None rnums = array_slice_values(s.mask, ijk_in, ijk_out, method='nearest')[:, 1] r = first_shown_region(s, rnums) if r is None: r = clicked_volume_region(segmentation, pointer_x, pointer_y) if r is None: print 'mouse down: no intercept with region' return None return r
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 matrix_products(mlist1, mlist2): plist = [] for m1 in mlist1: for m2 in mlist2: m1xm2 = multiply_matrices(m1, m2) plist.append(m1xm2) return plist
def coordinate_system_transform(from_cs, to_cs): global cst if cst: return cst[(from_cs, to_cs)] transform = cst e = icosahedron_edge_length() # Triangle edge length of unit icosahedron. from math import sqrt s25 = e/2 # Sin/Cos for angle between 2-fold and 5-fold axis c25 = sqrt(1 - s25*s25) s35 = e/sqrt(3) # Sin/Cos for angle between 3-fold and 5-fold axis c35 = sqrt(1-s35*s35) transform[('2n5','222')] = ((1,0,0,0), (0,c25,-s25,0), (0,s25,c25,0)) transform[('2n5','2n3')] = ((1, 0, 0, 0), (0, c35, s35, 0), (0, -s35, c35, 0)) # Axes permutations. transform[('222','222r')] = ((0,1,0,0), # 90 degree rotation about z (-1,0,0,0), (0,0,1,0)) transform[('2n3','2n3r')] = \ transform[('2n5','2n5r')] = ((-1,0,0,0), # 180 degree rotation about y (0,1,0,0), (0,0,-1,0)) transform[('n25','n25r')] = ((1,0,0,0), # 180 degree rotation about x (0,-1,0,0), (0,0,-1,0)) transform[('n25','2n5')] = ((0,1,0,0), # x <-> y and z -> -z (1,0,0,0), (0,0,-1,0)) # Extend to all pairs of transforms. tlist = [] while len(transform) > len(tlist): tlist = transform.keys() from Matrix import transpose_matrix, multiply_matrices # Add inverse transforms for f,t in tlist: if not (t,f) in transform: transform[(t,f)] = transpose_matrix(transform[(f,t)]) # Use transitivity for f1,t1 in tlist: for f2,t2 in tlist: if f2 == t1 and f1 != t2 and not (f1,t2) in transform: transform[(f1,t2)] = multiply_matrices(transform[(f2,t2)], transform[(f1,t1)]) return transform[(from_cs, to_cs)]
def transform(self, ncs_index, smtry_index, unit_cell_index): ncs = self.ncs_matrices[ncs_index] sym = self.smtry_matrices[smtry_index] from Matrix import multiply_matrices sym_ncs = multiply_matrices(sym, ncs) trans = unit_cell_translation(unit_cell_index, self.axes) trans_sym_ncs = translate_matrix(trans, sym_ncs) return trans_sym_ncs
def multiply_matrices(*tf_list): if len(tf_list) == 2: tf1, tf2 = tf_list r1 = tf1[:, :3] t1 = tf1[:, 3] r2 = tf2[:, :3] t2 = tf2[:, 3] from numpy import zeros, float, add from numpy import dot as matrix_multiply tf = zeros((3, 4), float) r = tf[:, :3] t = tf[:, 3] r[:] = matrix_multiply(r1, r2) t[:] = add(t1, matrix_multiply(r1, t2)) else: tf = multiply_matrices(*tf_list[1:]) tf = multiply_matrices(tf_list[0], tf) return tf
def space_group_matrices(space_group, a, b, c, alpha, beta, gamma): import space_groups sgtable = space_groups.space_group_symmetry_table() if not sgtable.has_key(space_group): return [] unit_cell_matrices = sgtable[space_group] r2r_symops = [] u2r = unit_cell_to_xyz_matrix(a, b, c, alpha, beta, gamma) from Matrix import invert_matrix, multiply_matrices r2u = invert_matrix(u2r) for u2u in unit_cell_matrices: r2u_sym = multiply_matrices(u2u, r2u) r2r = multiply_matrices(u2r, r2u_sym) r2r_symops.append(r2r) return r2r_symops
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 data_region_xyz_to_ijk_transform(data_region): xf = data_region.model_transform() xf.invert() from Matrix import xform_matrix, translation_matrix, multiply_matrices xyz_to_data_xyz = xform_matrix(xf) data_xyz_to_ijk = data_region.data.xyz_to_ijk_transform ijk_min = data_region.region[0] ijk_origin_shift = translation_matrix(map(lambda a: -a, ijk_min)) xyz_to_ijk_transform = multiply_matrices( ijk_origin_shift, data_xyz_to_ijk, xyz_to_data_xyz) return xyz_to_ijk_transform
def check_orthogonality(matrices, name, tolerance): from Matrix import transpose_matrix, multiply_matrices, is_identity_matrix for mindex, m in enumerate(matrices): mr = zero_translation(m) mrt = transpose_matrix(mr) p = multiply_matrices(mr, mrt) if not is_identity_matrix(p, tolerance): print('%s matrix %d is not orthogonal, tolerance %.3g' % (name, mindex, tolerance)) print_matrix(m, '%10.5f') print ' matrix times transpose = ' print_matrix(p, '%10.5f')
def check_orthogonality(matrices, name, tolerance): from Matrix import transpose_matrix, multiply_matrices, is_identity_matrix for mindex, m in enumerate(matrices): mr = zero_translation(m) mrt = transpose_matrix(mr) p = multiply_matrices(mr, mrt) if not is_identity_matrix(p, tolerance): print ('%s matrix %d is not orthogonal, tolerance %.3g' % (name, mindex, tolerance)) print_matrix(m, '%10.5f') print ' matrix times transpose = ' print_matrix(p, '%10.5f')
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 volume_plane_intercept(window_x, window_y, volume, k): from Matrix import multiply_matrices, xform_matrix, invert_matrix ijk_to_screen = multiply_matrices(xform_matrix(volume.model_transform()), volume.data.ijk_to_xyz_transform) screen_to_ijk = invert_matrix(ijk_to_screen) line = line_perpendicular_to_screen(window_x, window_y, screen_to_ijk) p, d = line if d[2] == 0: return None t = (k - p[2]) / d[2] ijk = (p[0] + t * d[0], p[1] + t * d[1], k) xyz = volume.data.ijk_to_xyz(ijk) return xyz
def volume_plane_intercept(window_x, window_y, volume, k): from Matrix import multiply_matrices, xform_matrix, invert_matrix ijk_to_screen = multiply_matrices(xform_matrix(volume.model_transform()), volume.data.ijk_to_xyz_transform) screen_to_ijk = invert_matrix(ijk_to_screen) line = line_perpendicular_to_screen(window_x, window_y, screen_to_ijk) p,d = line if d[2] == 0: return None t = (k - p[2]) / d[2] ijk = (p[0]+t*d[0], p[1]+t*d[1], k) xyz = volume.data.ijk_to_xyz(ijk) return xyz
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 create_surface(matrix, height, transform, color, interpolate, mesh, smoothing_factor, smoothing_iterations): if interpolate == 'cubic': matrix = cubic_interpolated_2d_array(matrix) from Matrix import multiply_matrices transform = multiply_matrices(transform, ((.5,0,0,0),(0,.5,0,0),(0,0,.5,0))) if mesh == 'isotropic': vertices, triangles = isotropic_surface_geometry(matrix) else: cell_diagonal_direction = mesh vertices, triangles = surface_geometry(matrix, cell_diagonal_direction) # Adjust vertex z range. x, z = vertices[:,0], vertices[:,2] zmin = z.min() xsize, zextent = x.max() - x.min(), z.max() - zmin z += -zmin if zextent > 0: if height is None: # Use 1/10 of grid voxels in x dimension. zscale = 0.1 * xsize / zextent else: # Convert zscale physical units to volume index z size. from Matrix import apply_matrix_without_translation, length zstep = length(apply_matrix_without_translation(transform, (0,0,1))) zscale = (height/zstep) / zextent z *= zscale # Transform vertices from index units to physical units. from _contour import affine_transform_vertices affine_transform_vertices(vertices, transform) if smoothing_factor != 0 and smoothing_iterations > 0: from _surface import smooth_vertex_positions smooth_vertex_positions(vertices, triangles, smoothing_factor, smoothing_iterations) from _surface import SurfaceModel sm = SurfaceModel() p = sm.addPiece(vertices, triangles, color) return sm
def create_volume_plane_surface(volume, height, interpolate = 'cubic', mesh = 'isotropic', colormap = 'rainbow', smoothing_factor = 0.3, smoothing_iterations = 0, color = (.7, .7, .7, 1), replace = True): m = volume.matrix() axes = [a for a in range(3) if m.shape[2-a] == 1] if len(axes) != 1: from chimera.replyobj import warning warning('Volume %s has more than one plane shown (%d,%d,%d)' % ((volume.name,) + tuple(reversed(m.shape)))) return axis = axes[0] m = m.squeeze() # Convert 3d array to 2d tf = volume.matrix_indices_to_xyz_transform() perm = {0: ((0,0,1,0),(1,0,0,0),(0,1,0,0)), # 2d matrix xyh -> 3d yzx 1: ((1,0,0,0),(0,0,1,0),(0,1,0,0)), # 2d matrix xyh -> 3d xzy 2: ((1,0,0,0),(0,1,0,0),(0,0,1,0))}[axis] from Matrix import multiply_matrices tf = multiply_matrices(tf, perm) s = create_surface(m, height, tf, color, interpolate, mesh, smoothing_factor, smoothing_iterations) s.name = volume.name + ' height' if colormap == 'rainbow': invert = not height is None and height < 0 tf = volume.data.ijk_to_xyz_transform normal = [tf[i][axis] for i in range(3)] colormap_surface(s, normal, rainbow_colormap(invert)) from chimera import openModels if replace: openModels.close([m for m in openModels.list() if getattr(m, 'topography_volume', None) == volume]) openModels.add([s]) s.openState.xform = volume.model_transform() s.topography_volume = volume return s
def clicked_volume_region(segmentation, pointer_x, pointer_y): r = None s = segmentation m = s.mask v = s.volume_data() if v and v.shown() and v.single_plane() and not m is None: box = v.region[:2] from Matrix import xform_matrix, multiply_matrices ijk_to_eye = multiply_matrices(xform_matrix(s.openState.xform), s.point_transform()) from VolumeViewer.slice import box_intercepts ijk_in, ijk_out = box_intercepts(pointer_x, pointer_y, ijk_to_eye, box, v) if not ijk_in is None: i, j, k = [int(round(h)) for h in ijk_in] ksz, jsz, isz = m.shape if i >= 0 and i < isz and j >= 0 and j < jsz and k >= 0 and k < ksz: rid = s.mask[k, j, i] r = s.id_to_region.get(rid, None) return r
def surface_geometry(plist, tf, pad): surfaces = [] for p in plist: surfs = [] va, ta = p.maskedGeometry(p.Solid) na = p.normals if isinstance(pad, (float,int)) and pad != 0: varray, tarray = offset_surface(va, ta, na, pad) elif isinstance(pad, (list,tuple)) and len(pad) == 2: varray, tarray = slab_surface(va, ta, na, pad) else: varray, tarray = va, ta if not tf is None: from Matrix import xform_matrix, multiply_matrices, is_identity_matrix vtf = multiply_matrices(tf, xform_matrix(p.model.openState.xform)) if not is_identity_matrix(vtf): apply_transform(vtf, varray) surfaces.append((varray, tarray)) return surfaces
def rotation_transform(axis, angle, center=(0, 0, 0)): axis = normalize_vector(axis) from math import pi, sin, cos arad = angle * pi / 180.0 sa = sin(arad) ca = cos(arad) k = 1 - ca ax, ay, az = axis tf = ((1 + k * (ax * ax - 1), -az * sa + k * ax * ay, ay * sa + k * ax * az, 0), (az * sa + k * ax * ay, 1 + k * (ay * ay - 1), -ax * sa + k * ay * az, 0), (-ay * sa + k * ax * az, ax * sa + k * ay * az, 1 + k * (az * az - 1), 0)) cx, cy, cz = center c_tf = ((1, 0, 0, cx), (0, 1, 0, cy), (0, 0, 1, cz)) inv_c_tf = ((1, 0, 0, -cx), (0, 1, 0, -cy), (0, 0, 1, -cz)) from Matrix import multiply_matrices rtf = multiply_matrices(c_tf, tf, inv_c_tf) return rtf
def surface_geometry(plist, tf, pad): surfaces = [] for p in plist: surfs = [] va, ta = p.maskedGeometry(p.Solid) na = p.normals if isinstance(pad, (float, int)) and pad != 0: varray, tarray = offset_surface(va, ta, na, pad) elif isinstance(pad, (list, tuple)) and len(pad) == 2: varray, tarray = slab_surface(va, ta, na, pad) else: varray, tarray = va, ta if not tf is None: from Matrix import xform_matrix, multiply_matrices, is_identity_matrix vtf = multiply_matrices(tf, xform_matrix(p.model.openState.xform)) if not is_identity_matrix(vtf): apply_transform(vtf, varray) surfaces.append((varray, tarray)) return surfaces
def copy_groups(from_seg, to_seg): # Find transform from to_seg mask indices to from_seg mask indices. from Matrix import multiply_matrices, invert_matrix, xform_matrix tf = multiply_matrices( invert_matrix(from_seg.point_transform()), invert_matrix(xform_matrix(from_seg.openState.xform)), xform_matrix(to_seg.openState.xform), to_seg.point_transform()) # Find from_seg regions containing to_seg region maximum points. fmask = from_seg.mask rlist = list(to_seg.regions) ijk = [r.max_point for r in rlist] from _interpolate import interpolate_volume_data rnums, outside = interpolate_volume_data(ijk, tf, fmask, 'nearest') # Find to_seg regions that have max_point in same from_seg region. fr2tr = {} id2r = from_seg.id_to_region for tr, frnum in zip(rlist, rnums): if frnum > 0: fr = id2r[frnum].top_parent() if fr in fr2tr: fr2tr[fr].append(tr) else: fr2tr[fr] = [tr] groups = [g for g in fr2tr.values() if len(g) > 1] # Form groups. for g in groups: r = to_seg.join_regions(g) for gr in g: gr.set_color(r.color) print 'Made %d groups for %s matching %s' % (len(groups), to_seg.name, from_seg.name)
def close_transforms(self, tf): a = rotation_angle(tf) # In range 0 to pi x, y, z = tf[0][3], tf[1][3], tf[2][3] c = (a, x, y, z) clist = self.bins.close_objects(c, self.spacing) if len(clist) == 0: return [] close = [] from Matrix import invert_matrix, multiply_matrices itf = invert_matrix(tf) for ctf in clist: dtf = multiply_matrices(ctf, itf) x, y, z = dtf[0][3], dtf[1][3], dtf[2][3] if (abs(x) < self.translation and abs(y) < self.translation and abs(z) < self.translation): a = rotation_angle(dtf) from math import pi if a < self.angle: close.append(ctf) return close
def update_force_field(self): pd = self.phantom_device if pd == None: return dr = self.data_region() if dr == None: self.remove_gradient_force() return data = dr.matrix(read_matrix = False) if data is None: self.remove_gradient_force() return xform = dr.model_transform() if xform == None: self.remove_gradient_force() return ijk_min, ijk_max = dr.ijk_bounds() bbox = chimera.BBox() bbox.llf = chimera.Point(*ijk_min) bbox.urb = chimera.Point(*ijk_max) cm = self.cursor_model cm.crosshair_bounding_box = bbox from Matrix import multiply_matrices, xform_matrix, invert_matrix btf = multiply_matrices(xform_matrix(xform), dr.data.ijk_to_xyz_transform) btf_inv = invert_matrix(btf) cm.crosshair_box_transform = (btf, btf_inv) # # TODO: These parameters are not adequate to determine whether volume # has changed. # volume_parameters = data.shape gf = self.gradient_force if gf and gf.volume_parameters != volume_parameters: self.remove_gradient_force() gf = None newtons_per_pound = 4.45 max_force_lbs = float_variable_value(self.maximum_force) max_force = newtons_per_pound * max_force_lbs force_constant = self.force_constant.value(default = 0) if self.auto_adjust_force_constant.get(): force_constant = self.adjust_force_constant(force_constant, max_force) ijk_to_vxyz = dr.matrix_indices_to_xyz_transform() from Matrix import multiply_matrices, xform_matrix, invert_matrix ijk_to_xyz = multiply_matrices(xform_matrix(xform), ijk_to_vxyz) xyz_to_ijk = invert_matrix(ijk_to_xyz) if gf == None: import _phantomcursor gf = _phantomcursor.Gradient_Force_Field(data, xyz_to_ijk, force_constant, max_force) gf.volume_parameters = volume_parameters self.gradient_force = gf pd.force_active = 0 pd.phantom_force_field = gf else: gf.maximum_force = max_force gf.force_constant = force_constant gf.xyz_to_grid_index = xyz_to_ijk force_on = (self.force_field.get() and (self.mode == 'cursor' or self.mode == 'move marker')) pd.force_active = force_on
def box_to_eye_transform(box_transform, xform): from Matrix import xform_matrix, multiply_matrices model_transform = xform_matrix(xform) # chimera.Xform -> 3x4 matrix transform = multiply_matrices(model_transform, box_transform) return transform
def icosahedral_matrix_table(): global icos_matrices if icos_matrices: return icos_matrices from math import cos, pi c = cos(2*pi/5) # .309016994 c2 = cos(4*pi/5) # -.809016994 icos_matrices['222'] = ( ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0)), ((c2, -0.5, c, 0.0), (-0.5, c, c2, 0.0), (c, c2, -0.5, 0.0)), ((0.0, 1.0, 0.0, 0.0), (0.0, 0.0, -1.0, 0.0), (-1.0, 0.0, 0.0, 0.0)), ((-c2, -0.5, -c, 0.0), (-0.5, -c, c2, 0.0), (c, -c2, -0.5, 0.0)), ((0.5, c, c2, 0.0), (-c, c2, -0.5, 0.0), (c2, 0.5, -c, 0.0)), ((-c, c2, -0.5, 0.0), (c2, 0.5, -c, 0.0), (0.5, c, c2, 0.0)), ((c2, 0.5, -c, 0.0), (0.5, c, c2, 0.0), (-c, c2, -0.5, 0.0)), ((c2, -0.5, -c, 0.0), (0.5, -c, c2, 0.0), (c, c2, 0.5, 0.0)), ((-c, -c2, -0.5, 0.0), (c2, -0.5, -c, 0.0), (-0.5, c, -c2, 0.0)), ((0.5, -c, c2, 0.0), (-c, -c2, -0.5, 0.0), (-c2, 0.5, c, 0.0)), ((0.0, 0.0, -1.0, 0.0), (-1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0)), ((-0.5, -c, c2, 0.0), (c, -c2, -0.5, 0.0), (-c2, -0.5, -c, 0.0)), ((-0.5, c, c2, 0.0), (c, c2, -0.5, 0.0), (c2, -0.5, c, 0.0)), ((-c, c2, -0.5, 0.0), (-c2, -0.5, c, 0.0), (-0.5, -c, -c2, 0.0)), ((c2, 0.5, -c, 0.0), (-0.5, -c, -c2, 0.0), (c, -c2, 0.5, 0.0)), ((0.5, c, c2, 0.0), (c, -c2, 0.5, 0.0), (-c2, -0.5, c, 0.0)), ((-0.5, c, c2, 0.0), (-c, -c2, 0.5, 0.0), (-c2, 0.5, -c, 0.0)), ((0.0, 0.0, -1.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, -1.0, 0.0, 0.0)), ((-0.5, -c, c2, 0.0), (-c, c2, 0.5, 0.0), (c2, 0.5, c, 0.0)), ((0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (-1.0, 0.0, 0.0, 0.0)), ((c2, 0.5, c, 0.0), (0.5, c, -c2, 0.0), (c, -c2, -0.5, 0.0)), ((-c2, 0.5, -c, 0.0), (0.5, -c, -c2, 0.0), (c, c2, -0.5, 0.0)), ((-c, -c2, -0.5, 0.0), (-c2, 0.5, c, 0.0), (0.5, -c, c2, 0.0)), ((0.5, -c, c2, 0.0), (c, c2, 0.5, 0.0), (c2, -0.5, -c, 0.0)), ((c2, -0.5, -c, 0.0), (-0.5, c, -c2, 0.0), (-c, -c2, -0.5, 0.0)), ((-c, c2, 0.5, 0.0), (c2, 0.5, c, 0.0), (-0.5, -c, c2, 0.0)), ((-c, -c2, 0.5, 0.0), (-c2, 0.5, -c, 0.0), (-0.5, c, c2, 0.0)), ((1.0, 0.0, 0.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, -1.0, 0.0)), ((c, -c2, -0.5, 0.0), (-c2, -0.5, -c, 0.0), (-0.5, -c, c2, 0.0)), ((c, c2, -0.5, 0.0), (c2, -0.5, c, 0.0), (-0.5, c, c2, 0.0)), ((-1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, -1.0, 0.0)), ((-c2, 0.5, -c, 0.0), (-0.5, c, c2, 0.0), (-c, -c2, 0.5, 0.0)), ((0.0, -1.0, 0.0, 0.0), (0.0, 0.0, -1.0, 0.0), (1.0, 0.0, 0.0, 0.0)), ((c2, 0.5, c, 0.0), (-0.5, -c, c2, 0.0), (-c, c2, 0.5, 0.0)), ((-0.5, -c, -c2, 0.0), (-c, c2, -0.5, 0.0), (-c2, -0.5, c, 0.0)), ((c, -c2, 0.5, 0.0), (c2, 0.5, -c, 0.0), (-0.5, -c, -c2, 0.0)), ((-c2, -0.5, c, 0.0), (0.5, c, c2, 0.0), (c, -c2, 0.5, 0.0)), ((-c2, 0.5, c, 0.0), (0.5, -c, c2, 0.0), (-c, -c2, -0.5, 0.0)), ((c, c2, 0.5, 0.0), (c2, -0.5, -c, 0.0), (0.5, -c, c2, 0.0)), ((-0.5, c, -c2, 0.0), (-c, -c2, -0.5, 0.0), (c2, -0.5, -c, 0.0)), ((0.0, 0.0, 1.0, 0.0), (-1.0, 0.0, 0.0, 0.0), (0.0, -1.0, 0.0, 0.0)), ((0.5, c, -c2, 0.0), (c, -c2, -0.5, 0.0), (c2, 0.5, c, 0.0)), ((0.5, -c, -c2, 0.0), (c, c2, -0.5, 0.0), (-c2, 0.5, -c, 0.0)), ((c, -c2, 0.5, 0.0), (-c2, -0.5, c, 0.0), (0.5, c, c2, 0.0)), ((-c2, -0.5, c, 0.0), (-0.5, -c, -c2, 0.0), (-c, c2, -0.5, 0.0)), ((-0.5, -c, -c2, 0.0), (c, -c2, 0.5, 0.0), (c2, 0.5, -c, 0.0)), ((0.5, -c, -c2, 0.0), (-c, -c2, 0.5, 0.0), (c2, -0.5, c, 0.0)), ((0.0, 0.0, 1.0, 0.0), (1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0)), ((0.5, c, -c2, 0.0), (-c, c2, 0.5, 0.0), (-c2, -0.5, -c, 0.0)), ((0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (1.0, 0.0, 0.0, 0.0)), ((-c2, -0.5, -c, 0.0), (0.5, c, -c2, 0.0), (-c, c2, 0.5, 0.0)), ((c2, -0.5, c, 0.0), (0.5, -c, -c2, 0.0), (-c, -c2, 0.5, 0.0)), ((c, c2, 0.5, 0.0), (-c2, 0.5, c, 0.0), (-0.5, c, -c2, 0.0)), ((-0.5, c, -c2, 0.0), (c, c2, 0.5, 0.0), (-c2, 0.5, c, 0.0)), ((-c2, 0.5, c, 0.0), (-0.5, c, -c2, 0.0), (c, c2, 0.5, 0.0)), ((c, -c2, -0.5, 0.0), (c2, 0.5, c, 0.0), (0.5, c, -c2, 0.0)), ((c, c2, -0.5, 0.0), (-c2, 0.5, -c, 0.0), (0.5, -c, -c2, 0.0)), ((-1.0, 0.0, 0.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0)), ((-c, c2, 0.5, 0.0), (-c2, -0.5, -c, 0.0), (0.5, c, -c2, 0.0)), ((-c, -c2, 0.5, 0.0), (c2, -0.5, c, 0.0), (0.5, -c, -c2, 0.0)), ) from Matrix import multiply_matrices for cs in coordinate_system_names: if cs != '222': t = coordinate_system_transform(cs, '222') tinv = coordinate_system_transform('222', cs) icos_matrices[cs] = [multiply_matrices(tinv, m, t) for m in icos_matrices['222']] return icos_matrices
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 update_force_field(self): pd = self.phantom_device if pd == None: return dr = self.data_region() if dr == None: self.remove_gradient_force() return data = dr.matrix(read_matrix=False) if data is None: self.remove_gradient_force() return xform = dr.model_transform() if xform == None: self.remove_gradient_force() return ijk_min, ijk_max = dr.ijk_bounds() bbox = chimera.BBox() bbox.llf = chimera.Point(*ijk_min) bbox.urb = chimera.Point(*ijk_max) cm = self.cursor_model cm.crosshair_bounding_box = bbox from Matrix import multiply_matrices, xform_matrix, invert_matrix btf = multiply_matrices(xform_matrix(xform), dr.data.ijk_to_xyz_transform) btf_inv = invert_matrix(btf) cm.crosshair_box_transform = (btf, btf_inv) # # TODO: These parameters are not adequate to determine whether volume # has changed. # volume_parameters = data.shape gf = self.gradient_force if gf and gf.volume_parameters != volume_parameters: self.remove_gradient_force() gf = None newtons_per_pound = 4.45 max_force_lbs = float_variable_value(self.maximum_force) max_force = newtons_per_pound * max_force_lbs force_constant = self.force_constant.value(default=0) if self.auto_adjust_force_constant.get(): force_constant = self.adjust_force_constant( force_constant, max_force) ijk_to_vxyz = dr.matrix_indices_to_xyz_transform() from Matrix import multiply_matrices, xform_matrix, invert_matrix ijk_to_xyz = multiply_matrices(xform_matrix(xform), ijk_to_vxyz) xyz_to_ijk = invert_matrix(ijk_to_xyz) if gf == None: import _phantomcursor gf = _phantomcursor.Gradient_Force_Field(data, xyz_to_ijk, force_constant, max_force) gf.volume_parameters = volume_parameters self.gradient_force = gf pd.force_active = 0 pd.phantom_force_field = gf else: gf.maximum_force = max_force gf.force_constant = force_constant gf.xyz_to_grid_index = xyz_to_ijk force_on = (self.force_field.get() and (self.mode == 'cursor' or self.mode == 'move marker')) pd.force_active = force_on
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