Пример #1
0
def check_matching_sizes(v1, v2, step, subregion, operation):

    if v1.data.size != v2.data.size:
        raise CommandError('Cannot %s grids of different size' % operation)
    if step or subregion:
        if not v1.same_region(v1.region, v2.region):
            raise CommandError('Cannot %s grids with different subregions' % operation)
Пример #2
0
def show_axis(tf, color, os):

    import Matrix
    axis, axis_point, angle, axis_shift = Matrix.axis_center_angle_shift(tf)
    if angle < 0.1:
        raise CommandError('Rotation angle is near zero (%g degrees)' % angle)

    have_box, box = os.bbox()
    if not have_box:
        # TODO: Chimera does not provide bounding box of full model.
        raise CommandError('First model must be visible to show axis')

    axis_center = Matrix.project_to_axis(box.center().data(), axis, axis_point)
    axis_length = max((box.urb - box.llf).data())
    hl = 0.5 * axis_length
    ap1 = map(lambda a, b: a - hl * b, axis_center, axis)
    ap2 = map(lambda a, b: a + hl * b, axis_center, axis)
    from VolumePath import Marker_Set, Link
    from VolumePath.markerset import chimera_color
    m = Marker_Set('rotation axis')
    mm = m.marker_model()
    mm.openState.xform = os.xform
    if color:
        mm.color = chimera_color(color)
    radius = 0.025 * axis_length
    m1 = m.place_marker(ap1, None, radius)
    m2 = m.place_marker(ap2, None, radius)
    Link(m1, m2, None, radius)
Пример #3
0
def parse_arg(fields, spec, cmd_name, session, akw):

    name, parse, pkw, multiple = arg_spec(spec)

    n = len(parse) if isinstance(parse, tuple) else 1
    if len(fields) < n:
        raise CommandError('%s: Missing argument for keyword "%s"'
                           % (cmd_name, name))
    
    try:
        if isinstance(parse, tuple):
            value = True if n == 0 else tuple(p(a, session, **pkw)
                                              for p,a in zip(parse,fields[:n]))
        else:
            value = parse(fields[0], session, **pkw)
    except CommandError as e:
        args = ' '.join(f for f in fields[:n])
        raise CommandError('%s invalid %s argument "%s": %s'
                           % (cmd_name, name, args, str(e)))
    except:
        args = ' '.join(f for f in fields[:n])
        raise
        raise CommandError('%s invalid %s argument "%s"'
                           % (cmd_name, name, args))
    if multiple:
        if name in akw:
            akw[name].append(value)
        else:
            akw[name] = [value]
    else:
        akw[name] = value

    return n
Пример #4
0
def spine(operation,
          regions,
          spacing=None,
          tipLength=None,
          color=None,
          showDiameter=False):

    sel = parse_object_specifier(regions, 'segmentation region')

    import Surface
    plist = Surface.selected_surface_pieces(sel, include_outline_boxes=False)
    from Segger.regions import Segmentation
    rlist = [
        p.region for p in plist
        if (hasattr(p, 'region') and isinstance(p.model, Segmentation))
    ]
    if len(rlist) == 0:
        raise CommandError('No segmentation regions specified: "%s"' % regions)

    if not (spacing is None or isinstance(spacing,
                                          (int, float)) and spacing > 0):
        raise CommandError('spacing must be positive numeric value')
    if not (tipLength is None or isinstance(tipLength,
                                            (int, float)) and tipLength > 0):
        raise CommandError('tipLength must be positive numeric value')

    if not color is None:
        from Commands import parse_color
        color = parse_color(color)

    if showDiameter:
        from _surface import SurfaceModel
        diam_model = SurfaceModel()
        diam_model.name = 'Diameters'
        from chimera import openModels
        openModels.add([diam_model], sameAs=rlist[0].segmentation)
    else:
        diam_model = None

    import spine
    from chimera import replyobj
    from PathLength import path_length
    for r in rlist:
        mset = spine.trace_spine(r, spacing, tipLength, color)
        slen = path_length([l.bond for l in mset.links()])
        r.set_attribute('spine length', slen)
        msg = 'Spine length for region %d is %.4g' % (r.rid, slen)
        dmax, dmin = spine.measure_diameter(r, mset, diam_model)
        if not dmax is None:
            r.set_attribute('diameter1', dmax)
            r.set_attribute('diameter2', dmin)
            msg += ', diameters %.4g, %.4g' % (dmax, dmin)
        kave, kmin, kmax = spine.measure_curvature(mset)
        if not kmax is None:
            r.set_attribute('curvature average', kave)
            r.set_attribute('curvature minimum', kmin)
            r.set_attribute('curvature maximum', kmax)
            msg += ', curvature %.4g (ave), %.4g (max), %.4g (min)' % (
                kave, kmax, kmin)
        replyobj.info(msg + '\n')
Пример #5
0
def color_arg(color, session):

    if isinstance(color, (tuple, list)):
        if len(color) == 4:
            return tuple(color)
        elif len(color) == 3:
            return tuple(color) + (1,)
    elif isinstance(color, str):
        fields = color.split(',')
        if len(fields) == 1:
            from webcolors import name_to_rgb
            try:
                rgb = name_to_rgb(color)
            except ValueError:
                raise CommandError('Unknown color: "%s"' % repr(color))
            return (rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0,1)
        else:
            try:
                rgba = tuple(float(c) for c in fields)
            except:
                raise CommandError('Unrecognized color: "%s"' % repr(color))
            if len(rgba) == 3:
                rgba = rgba + (1.0,)
            if len(rgba) == 4:
                return rgba
                
    raise CommandError('Unrecognized color: "%s"' % repr(color))
Пример #6
0
def float_arg(s, session, min = None, max = None):

    x = float(s)
    if not min is None and x < min:
        raise CommandError('Value must be >= %g, got %g' % (min, x))
    if not max is None and x > max:
        raise CommandError('Value must be <= %g, got %g' % (max, x))
    return x
Пример #7
0
def chain_arg(s, session):

    sel = parse_specifier(s, session)
    clist = sel.chains()
    if len(clist) == 0:
        raise CommandError('No chains specified')
    elif len(clist) > 1:
        raise CommandError('Multiple chains specified')
    return clist[0]
Пример #8
0
def model_arg(s, session):

    sel = parse_specifier(s, session)
    mlist = sel.models()
    if len(mlist) == 0:
        raise CommandError('No models specified')
    elif len(mlist) > 1:
        raise CommandError('Multiple models specified')
    return mlist[0]
Пример #9
0
def model_id_arg(s, session):

    if len(s) == 0 or s[0] != '#':
        raise CommandError('model id argument must start with "#", got "%s"' % s)
    try:
        mid = tuple(int(i) for i in s[1:].split('.'))
    except ValueError:
        raise CommandError('model id argument be integers separated by ".", got "%s"' % s)
    return mid
Пример #10
0
def openstate_arg(s, session):

    sel = parse_specifier(s, session)
    oslist = set([m.openState for m in sel.models()])
    if len(oslist) == 0:
        raise CommandError('No models specified')
    elif len(oslist) > 1:
        raise CommandError('Multiple coordinate systems specified')
    return oslist.pop()
Пример #11
0
def molecules_arg(s, session, min = 0):

    sel = parse_specifier(s, session)
    mlist = sel.molecules()
    if len(mlist) < min:
        if len(mlist) == 0:
            raise CommandError('No molecule specified, require %d' % min)
        else:
            raise CommandError('%d molecules specified, require at least %d' % (len(mlist), min))
    return mlist
Пример #12
0
def check_number(value, name, type = (float,int), allow_none = False,
                 positive = False, nonnegative = False):

    if allow_none and value is None:
        return
    if not isinstance(value, type):
        raise CommandError('%s must be number, got "%s"' % (name, str(value)))
    if positive and value <= 0:
        raise CommandError('%s must be > 0' % name)
    if nonnegative and value < 0:
        raise CommandError('%s must be >= 0' % name)
Пример #13
0
def parse_arguments(cmd_name, arg_string, session,
                    required_args = (), optional_args = (), keyword_args = ()):

    fields = split_fields(arg_string)
    n = len(fields)
    akw = {}
    a = 0
    spec = None
    args = []

    # Make keyword abbreviation table.
    kw_args = tuple(optional_args) + tuple(keyword_args)
    kwnames = [arg_specifier_name(s) for s in kw_args]
    kwt = abbreviation_table(kwnames)

    # Parse keyword arguments.
    keyword_spec = dict([(arg_specifier_name(s),s) for s in kw_args])
    while a < n:
        f = fields[a]
        fl = f.lower()
        if not fl in kwt:
            args.append(f)
            a += 1
            continue
        spec = keyword_spec[kwt[fl]]
        a += 1 + parse_arg(fields[a+1:], spec, cmd_name, session, akw)

    # Parse required arguments.
    a = 0
    na = len(args)
    for spec in required_args:
        if a >= na:
            raise CommandError('%s: Missing required argument "%s"'
                               % (cmd_name, arg_specifier_name(spec)))
        a += parse_arg(args[a:], spec, cmd_name, session, akw)

    # Parse optional arguments.
    for spec in optional_args:
        if a >= na:
            break
        a += parse_arg(args[a:], spec, cmd_name, session, akw)

    # Allow last positional argument to have multiple values.
    if spec:
        multiple = arg_spec(spec)[3]
        if multiple:
            while a < na:
                a += parse_arg(args[a:], spec, cmd_name, session, akw)

    if a < na:
        raise CommandError('%s: Extra argument "%s"' % (cmd_name, args[a]))

    return akw
Пример #14
0
def distance(operation,
             object1,
             object2,
             multiple=False,
             show=False,
             color=(0, 1, 1, 1)):

    a1 = object1.atoms()
    import Surface as s
    s1 = s.selected_surface_pieces(object1, include_outline_boxes=False)

    if len(a1) == 0 and len(s1) == 0:
        raise CommandError('No atoms or surfaces specified')

    a2 = object2.atoms()
    s2 = s.selected_surface_pieces(object2, include_outline_boxes=False)

    if len(a2) == 0 and len(s2) == 0:
        raise CommandError('No target atoms or surfaces')

    # Remove near stuff.
    if a1:
        a2 = list(set(a2).difference(a1))
    if s1:
        s2 = list(set(s2).difference(s1))

    name2 = object_name(a2, s2)
    xyz2 = point_array(a2, s2)

    if show:
        from Commands import parse_color
        color = parse_color(color)
        from _surface import SurfaceModel
        surf = SurfaceModel()
        surf.name = 'Distance measurement'
        from chimera import openModels
        openModels.add([surf])
    else:
        surf = None

    if multiple:
        pairs = [([a], []) for a in a1] + [([], [s]) for s in s1]
    else:
        pairs = [(a1, s1)]

    for a, s in pairs:
        name = object_name(a, s)
        xyz = point_array(a, s)
        report_distance(xyz, xyz2, name, name2, surf, color)
Пример #15
0
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)
Пример #16
0
def field_lines(operation,
                volume,
                lines=1000,
                startAbove=None,
                step=0.5,
                color=(.7, .7, .7, 1),
                lineWidth=1,
                tubeRadius=None,
                circleSubdivisions=12,
                markers=False,
                modelId=None):

    from VolumeViewer import Volume
    vlist = [m for m in volume if isinstance(m, Volume)]
    if len(vlist) == 0:
        raise CommandError('No volume specified')

    import Commands as CD
    rgba = CD.parse_color(color)
    model_id = None if modelId is None else CD.parse_model_id(modelId)

    import fieldlines
    for v in vlist:
        fieldlines.show_field_lines(v, lines, startAbove, step, rgba,
                                    lineWidth, tubeRadius, circleSubdivisions,
                                    markers, model_id)
Пример #17
0
def parse_value_color(vc):

    err = 'Colormap entry must be value,color: got "%s"' % vc
    svc = vc.split(',',1)
    if len(svc) != 2:
        raise CommandError(err)
    try:
        v = float(svc[0])
    except ValueError:
        raise CommandError(err)
    from Commands import convertColor
    try:
        c = convertColor(svc[1]).rgba()
    except:
        raise CommandError(err)
    return v, c
Пример #18
0
def symmetry(operation,
             volume,
             minimumCorrelation=0.99,
             nMax=8,
             helix=None,
             points=10000,
             set=True):

    from VolumeViewer import Volume
    vlist = [m for m in volume if isinstance(m, Volume)]
    if len(vlist) == 0:
        raise CommandError('No volume specified')

    if not helix is None:
        rise, angle, n, optimize = parse_helix_option(helix)

    import symmetry as S
    for v in vlist:
        if helix:
            syms, msg = S.find_helix_symmetry(v, rise, angle, n, optimize,
                                              nMax, minimumCorrelation, points)
        else:
            syms, msg = S.find_point_symmetry(v, nMax, minimumCorrelation,
                                              points)

        if set and syms:
            v.data.symmetries = syms

        from chimera.replyobj import info, status
        status(msg)
        info(msg + '\n')
Пример #19
0
def map_sum(operation, volume, aboveThreshold=None, step=1, subregion='all'):

    from VolumeViewer import Volume
    vlist = [m for m in volume if isinstance(m, Volume)]
    if len(vlist) == 0:
        raise CommandError('No volume specified')

    from Commands import parse_step, parse_subregion
    subregion_arg = subregion
    subregion = parse_subregion(subregion)
    step_arg = step
    step = parse_step(step)

    import numpy
    import VolumeStatistics as VS
    for v in vlist:
        m = v.matrix(step=step, subregion=subregion)
        if aboveThreshold is None:
            s = m.sum(dtype=numpy.float64)
        else:
            ma = (m >= aboveThreshold)
            na = ma.sum(dtype=numpy.int64)
            mt = ma.astype(m.dtype)
            mt *= m
            s = mt.sum(dtype=numpy.float64)
        descrip = v.name
        if step_arg != 1:
            descrip += ', step %s' % step_arg
        if subregion_arg != 'all':
            descrip += ', subregion %s' % subregion_arg
        if not aboveThreshold is None:
            descrip += ', level >= %.5g, npoints %d' % (aboveThreshold, na)
        msg = '%s: sum = %.5g' % (descrip, s)
        VS.message(msg, show_reply_log=True)
Пример #20
0
def filter_surfaces(surfaces):
    
    from ..molecule import Molecule
    surfs = set([s for s in surfaces if not isinstance(s, Molecule)])
    if len(surfs) == 0:
        raise CommandError('No surfaces specified')
    return surfs
Пример #21
0
def enum_arg(s, session, values, multiple = False, abbrev = False):

    val = abbreviation_table(values) if abbrev else dict((v,v) for v in values)
    if multiple:
        vlist = s.split(',')
        for v in vlist:
            if not v in val:
                raise CommandError('Values must be in %s, got "%s"'
                                   % (', '.join(values), s))
        e = [val[v] for v in vlist]
    elif s in val:
        e = val[s]
    else:
        raise CommandError('Value must be one of %s, got "%s"'
                           % (', '.join(values), s))
    return e
Пример #22
0
def volumes_arg(v, session):

    sel = parse_specifier(v, session)
    vlist = sel.maps()
    if len(vlist) == 0:
        raise CommandError('No volumes specified')
    return vlist
Пример #23
0
def map_values(operation, volume, atoms, name=None, report=10):

    from VolumeViewer import Volume
    vlist = [v for v in volume if isinstance(v, Volume)]
    if len(vlist) != 1:
        raise CommandError('No volume model specified')
    v = vlist[0]

    import AtomDensity
    if name is None:
        name = 'value_' + v.name
        name = AtomDensity.replace_special_characters(name, '_')
    AtomDensity.set_atom_volume_values(atoms, v, name)

    if report:
        arep = atoms[:report] if isinstance(report, int) else atoms
        values = '\n'.join(
            ['%s %.5g' % (a.oslIdent(), getattr(a, name)) for a in arep])
        n = len(atoms)
        t = '%s map values at %d atom positions\n%s\n' % (v.name, n, values)
        if n > len(arep):
            t += '...\n'
        if n == 1:
            s = '%s map value at atom %s = %.5g' % (
                v.name, atoms[0].oslIdent(), getattr(a, name))
        else:
            maxa = 3
            values = ', '.join(
                ['%.5g' % getattr(a, name) for a in atoms[:maxa]])
            if n > maxa:
                values += ', ...'
            s = '%s map values at %d atoms: %s' % (v.name, n, values)
        from chimera import replyobj
        replyobj.info(t)
        replyobj.status(s)
Пример #24
0
def map_statistics(operation, volume, step=1, subregion='all'):

    from VolumeViewer import Volume
    vlist = [m for m in volume if isinstance(m, Volume)]
    if len(vlist) == 0:
        raise CommandError('No volume specified')

    from Commands import parse_step, parse_subregion
    subregion_arg = subregion
    subregion = parse_subregion(subregion)
    step_arg = step
    step = parse_step(step)

    import VolumeStatistics as VS
    for v in vlist:
        m = v.matrix(step=step, subregion=subregion)
        mean, sd, rms = VS.mean_sd_rms(m)
        descrip = v.name
        if step_arg != 1:
            descrip += ', step %s' % step_arg
        if subregion_arg != 'all':
            descrip += ', subregion %s' % subregion_arg
        msg = '%s: mean = %.5g, SD = %.5g, RMS = %.5g' % (descrip, mean, sd,
                                                          rms)
        VS.message(msg, show_reply_log=True)
Пример #25
0
def single_volume(mlist):

    if mlist is None:
        return mlist
    vlist = filter_volumes(mlist)
    if len(vlist) != 1:
        raise CommandError('Must specify only one volume')
    return vlist[0]
Пример #26
0
def check_in_place(inPlace, volumes):

    if not inPlace:
        return
    nwv = [v for v in volumes if not v.data.writable]
    if nwv:
        names = ', '.join([v.name for v in nwv])
        raise CommandError("Can't modify volume in place: %s" % names)
Пример #27
0
def parse_object_specifier(spec, name='object'):

    from chimera import specifier
    try:
        sel = specifier.evalSpec(spec)
    except:
        raise CommandError('Bad %s specifier "%s"' % (name, spec))
    return sel
Пример #28
0
def float3_arg(s, session):

    fl = [float(x) for x in s.split(',')]
    if len(fl) != 3:
        raise CommandError('Require 3 comma-separated values, got %d' % len(fl))
    from numpy import array, float32
    a = array(fl, float32)
    return a
Пример #29
0
def ints_arg(s, session, allowed_counts = None):

    il = [int(x) for x in s.split(',')]
    if not allowed_counts is None and not len(il) in allowed_counts:
        allowed = ','.join('%d' % c for c in allowed_counts)
        raise CommandError('Wrong number of values, require %s, got %d'
                           % (allowed, len(il)))
    return il
Пример #30
0
def filter_volumes(models, keyword = ''):

    if keyword:
        keyword += ' '
        
    if isinstance(models, str):
        raise CommandError('No %svolumes specified by "%s"' % (keyword, models))
    
    from ..map import Volume
    from _volume import Volume_Model
    vids = set([v.id for v in models if isinstance(v, (Volume, Volume_Model))])
    for v in models:
        if not isinstance(v, (Volume, Volume_Model)) and not v.id in vids:
            raise CommandError('Model %s is not a volume' % v.name)
    volumes = [v for v in models if isinstance(v, Volume)]
    if len(volumes) == 0:
        raise CommandError('No %svolumes specified' % keyword)
    return volumes