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
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")
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
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
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
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
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
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
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
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)
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
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
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
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
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
def parse(text, session): from chimerax.core.commands import next_token group, atext, rest = next_token(text) return Symmetry(group, session), atext, rest
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)