예제 #1
0
 def parse(text, session):
     from chimerax.core.commands import AnnotationError, next_token
     if not text:
         raise AnnotationError("Expected %s" % SeqArg.name)
     token, text, rest = next_token(text)
     alignment = get_alignment_by_id(session, token)
     return alignment, text, rest
예제 #2
0
 def parse(text, session):
     from chimerax.core.commands import next_token
     token, text, rest = next_token(text)
     nv = _named_views(session).views
     if token in nv:
         return nv[token], text, rest
     raise AnnotationError("Expected a view name")
예제 #3
0
 def parse(text, session):
     from chimerax.core.commands import AnnotationError, next_token
     if not text:
         raise AnnotationError("Expected %s" % SeqArg.name)
     token, text, rest = next_token(text)
     if ':' not in token:
         align_id, seq_id = "", token
     else:
         align_id, seq_id = token.split(':', 1)
     if not align_id:
         aln_seq = None
         for aln in session.alignments.alignments:
             try:
                 seq = get_alignment_sequence(aln, seq_id)
             except MissingSequence:
                 pass
             else:
                 if aln_seq is None:
                     aln_seq = (aln, seq)
                 else:
                     raise AnnotationError("Multiple sequences match '%s'; please also specify the"
                         " alignment by prepending 'alignment-ID:'" % token)
         if aln_seq:
             return aln_seq, text, rest
         raise AnnotationError("No sequences match '%s'" % token)
     alignment = get_alignment_by_id(session, align_id)
     seq = get_alignment_sequence(alignment, seq_id)
     return (alignment, seq), text, rest
예제 #4
0
 def parse(text, session):
     import re
     token, text, rest = next_token(text, convert=True)
     canonical = re.sub("[^\w\d.]+", "_", token, re.UNICODE)
     simple = token.replace('-', '_')
     if simple != canonical:
         raise AnnotationError("Invalid bundle name")
     return token, text, rest
예제 #5
0
 def parse(text, session):
     token, text, rest = next_token(text)
     try:
         s = tuple(float(f) for f in token.split(','))
     except Exception:
         raise UserError('Must specify 2 comma-separated floats, got %s' % token)
     if len(s) != 2:
         raise UserError('Must specify 2 comma-separated floats, got %s' % token)
     return s, text, rest
예제 #6
0
 def parse(text, session):
     token, text, rest = next_token(text)
     try:
         s = tuple(int(f) for f in token.split(','))
     except Exception:
         raise UserError('Must specify integer or 3 comma-separated integers, got %s' % token)
     if len(s) == 1:
         s = (s[0],s[0],s[0])
     if len(s) != 3:
         raise UserError('Must specify integer or 3 comma-separated integers, got %s' % token)
     return s, text, rest
예제 #7
0
 def parse(text, session):
     token, text, rest = next_token(text)
     types = ('int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32',
              'float32', 'float64')
     if token in types:
         import numpy
         vt = getattr(numpy, token)
     else:
         raise UserError('Unknown data value type "%s", use %s'
                             % (token, ', '.join(types.keys())))
     return vt, text, rest
예제 #8
0
 def parse(text, session, default_step = 1):
     token, text, rest = next_token(text)
     try:
         s = tuple(int(f) for f in token.split(','))
     except Exception:
         s = ()
     n = len(s)
     if n < 2 or n > 3:
         raise UserError('Range argument must be 2 or 3 comma-separateed integer values, got %s' % text)
     i0,i1 = s[:2]
     step = s[2] if n >= 3 else default_step
     return (i0,i1,step), text, rest
예제 #9
0
 def parse(text, session):
     from chimerax.core.commands import next_token, AnnotationError
     token, text, rest = next_token(text)
     fields = token.split(',')
     if fields[0] not in ('x', 'y', 'z'):
         raise AnnotationError(
             'Planes argument first field must be x, y, or z, got "%s"' %
             fields[0])
     try:
         values = [int(f) for f in fields[1:]]
     except Exception:
         raise AnnotationError(
             'Planes arguments after axis must be integers')
     result = tuple([fields[0]] + values)
     return result, text, rest
예제 #10
0
def cmd_save(session, file_name, rest_of_line, *, log=True):
    tokens = []
    remainder = rest_of_line
    while remainder:
        token, token_log, remainder = next_token(remainder)
        remainder = remainder.lstrip()
        tokens.append(token)
    format_name = None
    for i in range(len(tokens)-2, -1, -2):
        test_token = tokens[i].lower()
        if "format".startswith(test_token):
            format_name = tokens[i+1]
    provider_cmd_text = "save " + " ".join([FileNameArg.unparse(file_name)]
        + [StringArg.unparse(token) for token in tokens])

    try:
        from .manager import NoSaverError
        mgr = session.save_command
        data_format= file_format(session, file_name, format_name)
        try:
            provider_args = mgr.save_args(data_format)
        except NoSaverError as e:
            raise LimitationError(str(e))

        # register a private 'save' command that handles the provider's keywords
        registry = RegisteredCommandInfo()
        keywords = {
            'format': DynamicEnum(lambda ses=session: format_names(ses)),
        }
        for keyword, annotation in provider_args.items():
            if keyword in keywords:
                raise ValueError("Save-provider keyword '%s' conflicts with builtin arg"
                    " of same name" % keyword)
            keywords[keyword] = annotation
        # for convenience, allow 'models' to be a second positional argument instead of a keyword
        if 'models' in keywords:
            optional = [('models', keywords['models'])]
            del keywords['models']
        else:
            optional = []
        desc = CmdDesc(required=[('file_name', SaveFileNameArg)], optional=optional,
            keyword=keywords.items(), hidden=mgr.hidden_args(data_format), synopsis="unnecessary")
        register("save", desc, provider_save, registry=registry)
    except BaseException as e:
        # want to log command even for keyboard interrupts
        log_command(session, "save", provider_cmd_text, url=_main_save_CmdDesc.url)
        raise
    Command(session, registry=registry).run(provider_cmd_text, log=log)
예제 #11
0
 def parse(text, session):
     token, text, rest = next_token(text)
     if token == 'all' or token == 'shown':
         return token, text, rest
     try:
         s = tuple(int(f) for f in token.split(','))
     except Exception:
         raise UserError('Must specify 6 comma-separated integers, got %s' % token)
     if len(s) != 6:
         raise UserError('Must specify 6 comma-separated integers, got %s' % token)
     r = s[:3], s[3:]
     for a in (0,1,2):
         if r[0][a] > r[1][a]:
             raise UserError('Volume region axis minimum values %d,%d,%d' % r[0] +
                             ' must be less than or equal to axis maximum values %d,%d,%d' % r[1])
     return r, text, rest
예제 #12
0
 def parse(text, session):
     from chimerax.core.commands import next_token, TopModelsArg, PlaceArg
     token, text, rest = next_token(text)
     fields = token.split(',')
     if len(fields) % 13:
         raise AnnotationError("Expected model id and 12 comma-separated numbers")
     mp = []
     while fields:
         tm, mtext, mrest = TopModelsArg.parse(fields[0], session)
         if len(tm) == 0:
             raise AnnotationError('No models specified by "%s"' % fields[0])
         p = PlaceArg.parse_place(fields[1:13])
         for m in tm:
             mp.append((m,p))
         fields = fields[13:]
     return mp, text, rest
예제 #13
0
 def parse(text, session):
     from chimerax.core.commands import next_token, AnnotationError
     if not text:
         raise AnnotationError('Missing index range argument')
     token, text, rest = next_token(text)
     fields = token.split(',')
     if len(fields) > 3:
         raise AnnotationError(
             "Index range has at most 3 comma-separated value")
     try:
         ses = [(None if f in ('', '.') else int(f)) for f in fields]
     except ValueError:
         raise AnnotationError("Index range values must be integers")
     if len(ses) == 1:
         ses.extend((ses[0], None))
     elif len(ses) == 2:
         ses.append(None)
     return ses, text, rest
예제 #14
0
 def parse(text, session):
     from chimerax.core.commands import next_token, AnnotationError
     if not text:
         raise AnnotationError("Expected %s" % HelixArg.name)
     token, text, rest = next_token(text)
     fields = token.split(',')
     optimize = (fields and fields[-1] == 'opt')
     if optimize:
         fields = fields[:-1]
     herr = 'Invalid helix option rise,angle[,n][,opt]'
     if len(fields) in (2, 3):
         try:
             rise, angle = [float(f) for f in fields[:2]]
             n = int(fields[2]) if len(fields) == 3 else None
         except ValueError:
             raise AnnotationError(herr)
     else:
         raise AnnotationError(herr)
     hparams = (rise, angle, n, optimize)
     return hparams, text, rest
예제 #15
0
 def parse(text, session):
     from chimerax.core.commands import AnnotationError, next_token
     if not text:
         raise AnnotationError("Expected %s" % NamedLabelsArg.name)
     lm = session_labels(session)
     token, text, rest = next_token(text)
     if lm is None:
         raise AnnotationError("No label with name: '%s'" % token)
     if lm.named_label(token) is None:
         possible = [
             name for name in lm.label_names() if name.startswith(token)
         ]
         if 'all'.startswith(token):
             possible.append('all')
         if not possible:
             raise AnnotationError("Unknown label identifier: '%s'" % token)
         possible.sort(key=len)
         token = possible[0]
     labels = lm.all_labels if token == 'all' else [lm.named_label(token)]
     return labels, token, rest
예제 #16
0
 def parse(text, session):
     from chimerax.core.commands import next_token
     group, atext, rest = next_token(text)
     return Symmetry(group, session), atext, rest
예제 #17
0
def cmd_open(session, file_names, rest_of_line, *, log=True):
    tokens = []
    remainder = rest_of_line
    while remainder:
        token, token_log, remainder = next_token(remainder)
        remainder = remainder.lstrip()
        tokens.append(token)
    provider_cmd_text = "open " + " ".join([FileNameArg.unparse(fn)
        for fn in file_names] + [StringArg.unparse(token) for token in tokens])
    try:
        database_name = format_name = None
        for i in range(len(tokens)-2, -1, -2):
            test_token = tokens[i].lower()
            if "format".startswith(test_token):
                format_name = tokens[i+1]
            elif "fromdatabase".startswith(test_token):
                database_name = tokens[i+1]

        from .manager import NoOpenerError
        mgr = session.open_command
        fetches, files = fetches_vs_files(mgr, file_names, format_name, database_name)
        if fetches:
            try:
                provider_args = mgr.fetch_args(fetches[0][1], format_name=fetches[0][2])
            except NoOpenerError as e:
                raise LimitationError(str(e))
        else:
            data_format = file_format(session, files[0], format_name)
            if data_format is None:
                # let provider_open raise the error, which will show the command
                provider_args = {}
            else:
                try:
                    provider_args = mgr.open_args(data_format)
                except NoOpenerError as e:
                    raise LimitationError(str(e))

        # register a private 'open' command that handles the provider's keywords
        registry = RegisteredCommandInfo()

        def database_names(mgr=mgr):
            return mgr.database_names

        keywords = {
            'format': DynamicEnum(lambda ses=session:format_names(ses)),
            'from_database': DynamicEnum(database_names),
            'ignore_cache': BoolArg,
            'name': StringArg
        }
        for keyword, annotation in provider_args.items():
            if keyword in keywords:
                raise ValueError("Open-provider keyword '%s' conflicts with builtin arg of"
                    " same name" % keyword)
            keywords[keyword] = annotation
        desc = CmdDesc(required=[('names', OpenFileNamesArg)], keyword=keywords.items(),
            synopsis="read and display data")
        register("open", desc, provider_open, registry=registry)
    except BaseException as e:
        # want to log command even for keyboard interrupts
        log_command(session, "open", provider_cmd_text, url=_main_open_CmdDesc.url)
        raise
    return Command(session, registry=registry).run(provider_cmd_text, log=log)