def morph_op(volumes, frames = 25, start = 0, playStep = 0.04, playDirection = 1, playRange = None, addMode = False, constantVolume = False, scaleFactors = None, hideOriginalMaps = True, subregion = 'all', step = 1, modelId = None): volumes = filter_volumes(volumes) check_number(frames, 'frames', int, nonnegative = True) check_number(start, 'start') check_number(playStep, 'playStep', nonnegative = True) if playRange is None: if addMode: prange = (-1.0,1.0) else: prange = (0.0,1.0) else: prange = parse_floats(playRange, 'playRange', 2) check_number(playDirection, 'playDirection') sfactors = parse_floats(scaleFactors, 'scaleFactors', len(volumes)) subregion = parse_subregion(subregion) step = parse_step(step) modelId = parse_model_id(modelId) vs = [tuple(v.matrix_size(step = step, subregion = subregion)) for v in volumes] if len(set(vs)) > 1: sizes = ' and '.join([str(s) for s in vs]) raise CommandError, "Volume grid sizes don't match: %s" % sizes from MorphMap import morph_maps morph_maps(volumes, frames, start, playStep, playDirection, prange, addMode, constantVolume, sfactors, hideOriginalMaps, subregion, step, modelId)
def parse_box(box, x, y, z, bname, xname, yname, zname): if box is None and x is None and y is None and z is None: return None if box: b6 = parse_floats(box, bname, 6) return (b6[:3], b6[3:]) box = ([None,None,None], [None,None,None]) for a,x,name in zip((0,1,2),(x,y,z),(xname,yname,zname)): if x: box[0][a], box[1][a] = parse_floats(x, name, 2) return box
def parse_box(box, x, y, z, bname, xname, yname, zname): if box is None and x is None and y is None and z is None: return None if box: b6 = parse_floats(box, bname, 6) return (b6[:3], b6[3:]) box = ([None, None, None], [None, None, None]) for a, x, name in zip((0, 1, 2), (x, y, z), (xname, yname, zname)): if x: box[0][a], box[1][a] = parse_floats(x, name, 2) return box
def parse_rotation(rotation, qrotation): if rotation: aa = parse_floats(rotation, 'rotation', 4) axis, angle = aa[:3], aa[3] elif qrotation: q = parse_floats(qrotation, 'qrotation', 4) from Matrix import norm from math import atan2, pi angle = (360/pi)*atan2(norm(q[:3]), q[3]) axis = q[:3] else: axis = angle = None if axis and tuple(axis) == (0,0,0): axis = angle = None return axis, angle
def sphere_shape(radius = 10.0, center = None, rotation = None, qrotation = None, coordinateSystem = None, divisions = 72, color = (.745,.745,.745,1), mesh = False, linewidth = 1, slab = None, modelName = None, modelId = None): try: r = parse_floats(radius, 'radius', 3) except CommandError: check_number(radius, 'radius', nonnegative = True) r = (radius, radius, radius) check_number(divisions, 'divisions', positive = True) check_number(linewidth, 'linewidth', nonnegative = True) model_id = parse_model_id(modelId) varray, tarray = icosahedral_geometry(1.0, divisions, sphere_factor = 1) for a in range(3): varray[:,a] *= r[a] edge_mask = None if modelName is None: modelName = 'sphere' if r[1] == r[0] and r[2] == r[0] else 'ellipsoid' show_surface(varray, tarray, edge_mask, color, mesh, linewidth, center, rotation, qrotation, coordinateSystem, slab, model_id, modelName)
def parse_rotation(rotation, qrotation): if rotation: aa = parse_floats(rotation, 'rotation', 4) axis, angle = aa[:3], aa[3] elif qrotation: q = parse_floats(qrotation, 'qrotation', 4) from Matrix import norm from math import atan2, pi angle = (360 / pi) * atan2(norm(q[:3]), q[3]) axis = q[:3] else: axis = angle = None if axis and tuple(axis) == (0, 0, 0): axis = angle = None return axis, angle
def subtract_op(vol1, vol2, onGrid=None, boundingGrid=False, subregion='all', step=1, gridSubregion='all', gridStep=1, inPlace=False, scaleFactors=None, minRMS=False, modelId=None): vol1 = filter_volumes(vol1) vol2 = filter_volumes(vol2) if len(vol1) != 1 or len(vol2) != 1: raise CommandError, 'vop subtract operation requires exactly two volumes' if minRMS and scaleFactors: raise CommandError, 'vop subtract cannot specify both minRMS and scaleFactors options.' if minRMS: mult = (1, 'minrms') elif scaleFactors: m0, m1 = parse_floats(scaleFactors, 'scaleFactors', 2) mult = (m0, -m1) else: mult = (1, -1) add_op(vol1 + vol2, onGrid, boundingGrid, subregion, step, gridSubregion, gridStep, inPlace, mult, modelId)
def add_op(volumes, onGrid = None, boundingGrid = None, subregion = 'all', step = 1, gridSubregion = 'all', gridStep = 1, inPlace = False, scaleFactors = None, modelId = None): volumes = filter_volumes(volumes) if boundingGrid is None and not inPlace: boundingGrid = (onGrid is None) if onGrid is None: onGrid = volumes[:1] onGrid = filter_volumes(onGrid, 'onGrid') subregion = parse_subregion(subregion) step = parse_step(step) gridSubregion = parse_subregion(gridSubregion, 'gridSubregion') gridStep = parse_step(gridStep, 'gridStep') if inPlace: if boundingGrid or gridStep != 1 or gridSubregion != 'all': raise CommandError, "Can't use inPlace option with boundingGrid or gridStep or gridSubregion options" for gv in onGrid: if not gv.data.writable: raise CommandError, "Can't modify volume in place: %s" % gv.name if not gv in volumes: raise CommandError, "Can't change grid in place" if isinstance(scaleFactors, basestring): scaleFactors = parse_floats(scaleFactors, 'scaleFactors', len(volumes)) modelId = parse_model_id(modelId) for gv in onGrid: add_operation(volumes, subregion, step, gv, gridSubregion, gridStep, boundingGrid, inPlace, scaleFactors, modelId)
def sphere_shape(radius=10.0, center=None, rotation=None, qrotation=None, coordinateSystem=None, divisions=72, color=(.745, .745, .745, 1), mesh=False, linewidth=1, slab=None, modelName=None, modelId=None): try: r = parse_floats(radius, 'radius', 3) except CommandError: check_number(radius, 'radius', nonnegative=True) r = (radius, radius, radius) check_number(divisions, 'divisions', positive=True) check_number(linewidth, 'linewidth', nonnegative=True) model_id = parse_model_id(modelId) varray, tarray = icosahedral_geometry(1.0, divisions, sphere_factor=1) for a in range(3): varray[:, a] *= r[a] edge_mask = None if modelName is None: modelName = 'sphere' if r[1] == r[0] and r[2] == r[0] else 'ellipsoid' show_surface(varray, tarray, edge_mask, color, mesh, linewidth, center, rotation, qrotation, coordinateSystem, slab, model_id, modelName)
def octant_complement_op(volumes, center = None, iCenter = None, subregion = 'all', step = 1, inPlace = False, fillValue = 0, modelId = None): volumes = filter_volumes(volumes) center = parse_floats(center, 'center', 3) iCenter = parse_floats(iCenter, 'iCenter', 3) subregion = parse_subregion(subregion) step = parse_step(step) check_in_place(inPlace, volumes) check_number(fillValue, 'fillValue') modelId = parse_model_id(modelId) outside = False for v in volumes: octant_operation(v, outside, center, iCenter, subregion, step, inPlace, fillValue, modelId)
def add_op(volumes, onGrid=None, boundingGrid=None, subregion='all', step=1, gridSubregion='all', gridStep=1, inPlace=False, scaleFactors=None, modelId=None): volumes = filter_volumes(volumes) if boundingGrid is None and not inPlace: boundingGrid = (onGrid is None) if onGrid is None: onGrid = volumes[:1] onGrid = filter_volumes(onGrid, 'onGrid') subregion = parse_subregion(subregion) step = parse_step(step) gridSubregion = parse_subregion(gridSubregion, 'gridSubregion') gridStep = parse_step(gridStep, 'gridStep') if inPlace: if boundingGrid or gridStep != 1 or gridSubregion != 'all': raise CommandError, "Can't use inPlace option with boundingGrid or gridStep or gridSubregion options" for gv in onGrid: if not gv.data.writable: raise CommandError, "Can't modify volume in place: %s" % gv.name if not gv in volumes: raise CommandError, "Can't change grid in place" if isinstance(scaleFactors, basestring): scaleFactors = parse_floats(scaleFactors, 'scaleFactors', len(volumes)) modelId = parse_model_id(modelId) for gv in onGrid: add_operation(volumes, subregion, step, gv, gridSubregion, gridStep, boundingGrid, inPlace, scaleFactors, modelId)
def show_surface(varray, tarray, edge_mask, color, mesh, linewidth, center, rotation, qrotation, coordinate_system, slab, model_id, shape_name): from Commands import parse_rgba rgba = parse_rgba(color) if coordinate_system: from Commands import openStateFromSpec os = openStateFromSpec(coordinate_system, 'coordinateSystem') cxf = os.xform else: cxf = None s = surface_model(model_id, shape_name, cxf) sxf = s.openState.xform sxfinv = sxf.inverse() if cxf is None: cxf = sxf axis, angle = parse_rotation(rotation, qrotation) if axis: from chimera import Vector csaxis = cxf.apply(Vector(*axis)).data() from Matrix import rotation_transform saxis = sxfinv.apply(Vector(*csaxis)).data() rtf = rotation_transform(saxis, angle) from _contour import affine_transform_vertices affine_transform_vertices(varray, rtf) if center: from Commands import parseCenterArg center, csys = parseCenterArg(center, 'shape') if csys: center = csys.xform.apply(center) else: center = cxf.apply(center) scenter = sxfinv.apply(center) varray += scenter.data() if not slab is None: if isinstance(slab, (float,int)): pad = (-0.5*slab, 0.5*slab) else: pad = parse_floats(slab, 'slab', 2) import _surface narray = _surface.calculate_vertex_normals(varray, tarray) from Mask import depthmask varray, tarray = depthmask.slab_surface(varray, tarray, narray, pad) p = s.addPiece(varray, tarray, rgba) if mesh: p.displayStyle = p.Mesh if not edge_mask is None: p.setEdgeMask(edge_mask) # Hide spokes of hexagons. p.lineThickness = linewidth p.save_in_session = True
def show_surface(varray, tarray, edge_mask, color, mesh, linewidth, center, rotation, qrotation, coordinate_system, slab, model_id, shape_name): from Commands import parse_rgba rgba = parse_rgba(color) if coordinate_system: from Commands import openStateFromSpec os = openStateFromSpec(coordinate_system, 'coordinateSystem') cxf = os.xform else: cxf = None s = surface_model(model_id, shape_name, cxf) sxf = s.openState.xform sxfinv = sxf.inverse() if cxf is None: cxf = sxf axis, angle = parse_rotation(rotation, qrotation) if axis: from chimera import Vector csaxis = cxf.apply(Vector(*axis)).data() from Matrix import rotation_transform saxis = sxfinv.apply(Vector(*csaxis)).data() rtf = rotation_transform(saxis, angle) from _contour import affine_transform_vertices affine_transform_vertices(varray, rtf) if center: from Commands import parseCenterArg center, csys = parseCenterArg(center, 'shape') if csys: center = csys.xform.apply(center) else: center = cxf.apply(center) scenter = sxfinv.apply(center) varray += scenter.data() if not slab is None: if isinstance(slab, (float, int)): pad = (-0.5 * slab, 0.5 * slab) else: pad = parse_floats(slab, 'slab', 2) import _surface narray = _surface.calculate_vertex_normals(varray, tarray) from Mask import depthmask varray, tarray = depthmask.slab_surface(varray, tarray, narray, pad) p = s.addPiece(varray, tarray, rgba) if mesh: p.displayStyle = p.Mesh if not edge_mask is None: p.setEdgeMask(edge_mask) # Hide spokes of hexagons. p.lineThickness = linewidth p.save_in_session = True
def parse_offset(offset): from Commands import check_number, parse_floats if isinstance(offset, (basestring, tuple, list)): o1, o2, n = parse_floats(offset, 'offset', 3) if n <= 1: raise CommandError, 'Offset count must be greater than 1' offset = [o1 + (o2 - o1) * float(i) / (n - 1) for i in range(n)] else: check_number(offset, 'offset') return offset
def parse_offset(offset): from Commands import check_number, parse_floats if isinstance(offset, (basestring,tuple,list)): o1, o2, n = parse_floats(offset, 'offset', 3) if n <= 1: raise CommandError, 'Offset count must be greater than 1' offset = [o1 + (o2-o1)*float(i)/(n-1) for i in range(n)] else: check_number(offset, 'offset') return offset
def octant_complement_op(volumes, center=None, iCenter=None, subregion='all', step=1, inPlace=False, fillValue=0, modelId=None): volumes = filter_volumes(volumes) center = parse_floats(center, 'center', 3) iCenter = parse_floats(iCenter, 'iCenter', 3) subregion = parse_subregion(subregion) step = parse_step(step) check_in_place(inPlace, volumes) check_number(fillValue, 'fillValue') modelId = parse_model_id(modelId) outside = False for v in volumes: octant_operation(v, outside, center, iCenter, subregion, step, inPlace, fillValue, modelId)
def morph_op(volumes, frames=25, start=0, playStep=0.04, playDirection=1, playRange=None, addMode=False, constantVolume=False, scaleFactors=None, hideOriginalMaps=True, subregion='all', step=1, modelId=None): volumes = filter_volumes(volumes) check_number(frames, 'frames', int, nonnegative=True) check_number(start, 'start') check_number(playStep, 'playStep', nonnegative=True) if playRange is None: if addMode: prange = (-1.0, 1.0) else: prange = (0.0, 1.0) else: prange = parse_floats(playRange, 'playRange', 2) check_number(playDirection, 'playDirection') sfactors = parse_floats(scaleFactors, 'scaleFactors', len(volumes)) subregion = parse_subregion(subregion) step = parse_step(step) modelId = parse_model_id(modelId) vs = [ tuple(v.matrix_size(step=step, subregion=subregion)) for v in volumes ] if len(set(vs)) > 1: sizes = ' and '.join([str(s) for s in vs]) raise CommandError, "Volume grid sizes don't match: %s" % sizes from MorphMap import morph_maps morph_maps(volumes, frames, start, playStep, playDirection, prange, addMode, constantVolume, sfactors, hideOriginalMaps, subregion, step, modelId)
def mask(volumes, surfaces, axis = None, fullMap = False, pad = 0., slab = None, sandwich = True, invertMask = False): from Commands import CommandError, filter_volumes, parse_floats vlist = filter_volumes(volumes) from Surface import selected_surface_pieces glist = selected_surface_pieces(surfaces, include_outline_boxes = False) if len(glist) == 0: raise CommandError, 'No surfaces specified' axis = parse_floats(axis, 'axis', 3, (0,1,0)) if not isinstance(fullMap, (bool,int)): raise CommandError, 'fullMap option value must be true or false' if not isinstance(invertMask, (bool,int)): raise CommandError, 'invertMask option value must be true or false' if not isinstance(pad, (float,int)): raise CommandError, 'pad option value must be a number' if isinstance(slab, (float,int)): pad = (-0.5*slab, 0.5*slab) elif not slab is None: pad = parse_floats(slab, 'slab', 2) if not isinstance(sandwich, bool): raise CommandError, 'sandwich option value must be true or false' from depthmask import surface_geometry, masked_volume from Matrix import xform_matrix, invert_matrix for v in vlist: tf = invert_matrix(xform_matrix(v.model_transform())) surfs = surface_geometry(glist, tf, pad) masked_volume(v, surfs, axis, fullMap, sandwich, invertMask)
def contact_area(operation, surf1, surf2, distance, show=True, color=(1, 0, 0, 1), offset=1, slab=None, smooth=False, optimize=True): plist = [] import Surface for spec in (surf1, surf2): s = parse_object_specifier(spec, 'surface') p = Surface.selected_surface_pieces(s, include_outline_boxes=False) if len(p) == 0: raise CommandError('%s has no surface pieces' % spec) elif len(p) > 1: raise CommandError('%s has %d surface pieces, require 1' % (spec, len(p))) plist.append(p[0]) p1, p2 = plist from Commands import parse_color color = parse_color(color) if not show: color = None from Commands import check_number check_number(offset, 'offset') if not slab is None: if isinstance(slab, (float, int)): slab = (-0.5 * slab, 0.5 * slab) else: from Commands import parse_floats slab = parse_floats(slab, 'slab', 2) offset = None import contactarea as c area = c.contact_area(p1, p2, distance, color, offset, slab, smooth, optimize) from chimera import replyobj replyobj.info('Contact area on %s within distance %.4g\nof %s = %.4g\n' % (p1.model.name, distance, p2.model.name, area)) replyobj.status('Contact area = %.4g' % area)
def subtract_op(vol1, vol2, onGrid = None, boundingGrid = False, subregion = 'all', step = 1, gridSubregion = 'all', gridStep = 1, inPlace = False, scaleFactors = None, minRMS = False, modelId = None): vol1 = filter_volumes(vol1) vol2 = filter_volumes(vol2) if len(vol1) != 1 or len(vol2) != 1: raise CommandError, 'vop subtract operation requires exactly two volumes' if minRMS and scaleFactors: raise CommandError, 'vop subtract cannot specify both minRMS and scaleFactors options.' if minRMS: mult = (1,'minrms') elif scaleFactors: m0,m1 = parse_floats(scaleFactors, 'scaleFactors', 2) mult = (m0,-m1) else: mult = (1,-1) add_op(vol1+vol2, onGrid, boundingGrid, subregion, step, gridSubregion, gridStep, inPlace, mult, modelId)