Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #6
0
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)
Пример #7
0
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	
Пример #8
0
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
Пример #11
0
    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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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
Пример #16
0
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)]
Пример #17
0
    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
Пример #18
0
    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
Пример #21
0
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
Пример #22
0
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
Пример #23
0
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
Пример #24
0
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')
Пример #25
0
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
Пример #27
0
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
Пример #28
0
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
Пример #29
0
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
Пример #30
0
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
Пример #31
0
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
Пример #32
0
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
Пример #33
0
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
Пример #36
0
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)
Пример #37
0
    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
Пример #38
0
  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
Пример #40
0
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
Пример #42
0
    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
Пример #43
0
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