def do_fusering(self): ring_names = self.ringname.text() new_name = self.new_ring_name.text() minimize_ring = self.minimize_ring.isChecked() self.settings.minimize_ring = minimize_ring if len(new_name.strip()) > 0: run( self.session, "fuseRing sel rings %s newName %s modify %s minimize %s" % ( ring_names, new_name, self.close_previous_bool, minimize_ring, ) ) else: run( self.session, "fuseRing sel rings %s modify %s minimize %s" % ( ring_names, self.close_previous_bool, minimize_ring, ) )
def spotlight_radius(session, radius: 'float', managers: 'list' = []): ''' Adjust the radius of the "spotlight" (the sphere of density around the centre of rotation). Args: radius: the desired radius in Angstroms managers: a list of the IDs corresponding to the Clipper top-level managers for the models for which the radius is to be updated. To update the radius for all currently-loaded models/maps, either omit the argument or provide an empty list. Returs: empty dict ''' from chimerax.core.commands import run if len(managers): mgr_string = '#{}'.format(','.join(managers)) else: mgr_string = '' run(session, 'clipper spotlight {} radius {}'.format(mgr_string, radius), log=False) return {}
def fetch_additional_scores(self, refresh=False): self.scores_fetched = True from chimerax.core.commands import run, concise_model_spec run( self.session, "modeller scores %s refresh %s" % (concise_model_spec( self.session, self.models), str(refresh).lower()))
def _process_subdialog(self, sd_type): sd = self.subdialogs[sd_type] from chimerax.core.commands import run if sd_type == "H-Bonds": cmd_name, spec, args = sd.hbonds_gui.get_command() res = self.mgr.base_residue base_spec = "#!%s & ~%s" % (res.structure.id_string, res.string(style="command")) if self.ignore_solvent_button.isChecked(): base_spec += " & ~solvent" hbs = run( self.session, "%s %s %s restrict #%s & ~@c,ca,n" % (cmd_name, base_spec, args, self.mgr.group.id_string)) AtomicStructure.register_attr(self.session, "num_hbonds", self.registerer, attr_type=int) for rotamer in self.mgr.rotamers: rotamer.num_hbonds = 0 for d, a in hbs: if d.structure == res.structure: a.structure.num_hbonds += 1 else: d.structure.num_hbonds += 1 if sd_type in self.opt_columns: self.table.update_column(self.opt_columns[sd_type], data=True) else: self.opt_columns[sd_type] = self.table.add_column(sd_type, "num_hbonds", format="%d") elif sd_type == "Clashes": cmd_name, spec, args = sd.clashes_gui.get_command() res = self.mgr.base_residue base_spec = "#!%s & ~%s" % (res.structure.id_string, res.string(style="command")) if self.ignore_solvent_button.isChecked(): base_spec += " & ~solvent" clashes = run( self.session, "%s %s %s restrict #%s & ~@c,ca,n" % (cmd_name, base_spec, args, self.mgr.group.id_string)) AtomicStructure.register_attr(self.session, "num_clashes", self.registerer, attr_type=int) for rotamer in self.mgr.rotamers: rotamer.num_clashes = 0 for a, clashing in clashes.items(): if a.structure != res.structure: a.structure.num_clashes += len(clashing) if sd_type in self.opt_columns: self.table.update_column(self.opt_columns[sd_type], data=True) else: self.opt_columns[sd_type] = self.table.add_column( sd_type, "num_clashes", format="%d") else: # Density vol = sd.vol_list.value if not vol: return self._eval_vol(vol) self._update_button_text()
def _setting_option_cb(self, opt): from chimerax.core.commands import run, StringArg session = self.alignment.session align_arg = "%s " % StringArg.unparse(str(self.alignment)) \ if len(session.alignments.alignments) > 1 else "" run(session, "seq header %s%s setting %s %s" % (align_arg, self.ident, opt.attr_name, StringArg.unparse(str(opt.value))))
def open_rmf(session, path): """Read an RMF file from a named file. Returns the 2-tuple return value appropriate for the ``chimerax.core.toolshed.BundleAPI.open_file`` method. """ rl = _RMFLoader() r, structures = rl.load(path, session) numframes = r.get_number_of_frames() producer = r.get_producer() status = ("Opened RMF file%s with %d frame%s." % (" produced with %s," % producer if producer else "", numframes, "" if numframes == 1 else "s")) if structures[0]._rmf_resolutions: status += (" Representation read at the following resolutions: %s." % ", ".join("%.1f" % i for i in sorted(structures[0]._rmf_resolutions))) if numframes > 1: status += (" Only the first frame was read; to read additional " "frames, use the 'rmf readtraj' command.") if session.ui.is_gui: from chimerax.core.commands import run run(session, 'tool show "RMF Viewer"', log=False) return structures, status
def callback(self, session): from chimerax.atomic import selected_atoms a1, a2 = selected_atoms(session) command = "dist %s %s" % (a1.string(style="command line"), a2.string(style="command line")) from chimerax.core.commands import run run(session, command)
def mouse_up(self, event): x, y = event.position() pick = self.view.picked_object(x, y) if not self.substituent or event.shift_down() or not pick: _SubstituentSelector(self.session, "pick substituent") return if isinstance(pick, PickedAtom): atom = pick.atom if SubstituteMouseMode.resName: run( self.session, "substitute %s substituent %s minimize true newName %s newResidue %s useRemoteness %s" % ( atom.atomspec, self.substituent, self.resName, repr(self.newRes), repr(self.useRemoteness), )) else: run( self.session, "substitute %s substituent %s minimize true newResidue %s useRemoteness %s" % ( atom.atomspec, self.substituent, repr(self.newRes), repr(self.useRemoteness), ))
def alignment_notification(self, note_name, note_data): alignment = self.alignment if note_name == alignment.NOTE_MOD_ASSOC: assoc_aseqs = set() if note_data[0] != alignment.NOTE_DEL_ASSOC: match_maps = note_data[1] else: match_maps = [note_data[1]['match map']] for match_map in match_maps: aseq = match_map.align_seq assoc_aseqs.add(aseq) for aseq in assoc_aseqs: self.seq_canvas.assoc_mod(aseq) self._update_errors_gaps(aseq) if self.alignment.intrinsic: self.show_ss(True) if hasattr(self, 'associations_tool'): self.associations_tool._assoc_mod(note_data) elif note_name == alignment.NOTE_PRE_DEL_SEQS: self.region_browser._pre_remove_lines(note_data) elif note_name == alignment.NOTE_DESTROYED: self.delete() elif note_name == alignment.NOTE_COMMAND: from .cmd import run run(self.session, self, note_data) self.seq_canvas.alignment_notification(note_name, note_data)
def run_provider(session, name): what = _providers[name] if not isinstance(what, str): what(session) else: from chimerax.core.commands import run run(session, what)
def destroy(self): if self.show_values[ 'checking_frequency'] and not self.ok_radio.isChecked(): # continuous monitoring is on, turn it off from chimerax.core.commands import run run(self.session, "~" + self.cmd_name) super().destroy()
def run(self, session, status=True): f = self.func s = session if status: self.log(s.logger) # User command string if isinstance(f, str): from chimerax.core import commands commands.run(s, f) return # Python function if self.atoms_arg: f(shortcut_atoms(s)) elif self.each_map: for m in shortcut_maps(s): f(m) elif self.each_molecule: for m in shortcut_molecules(s): f(m) elif self.each_surface: for m in shortcut_surfaces(s): f(m) elif self.view_arg: v = s.main_view f(v) elif self.mouse_modes_arg: m = s.ui.mouse_modes f(m) elif self.session_arg: f(s) else: f()
def log_torsion_command(bond_rotator): bond = bond_rotator.rotation.bond ms_atom = bond_rotator.moving_side fs_atom = bond.other_atom(ms_atom) ms_atom2 = _connected_atom(ms_atom, fs_atom) fs_atom2 = _connected_atom(fs_atom, ms_atom) if ms_atom2 is None or fs_atom2 is None: return # No connected atom to define a torsion side = '' if bond.smaller_side is ms_atom else 'move large' from chimerax.geometry import dihedral torsion = dihedral(fs_atom2.scene_coord, fs_atom.scene_coord, ms_atom.scene_coord, ms_atom2.scene_coord) res = ms_atom.residue if ms_atom2.residue is res and fs_atom.residue is res and fs_atom2.residue is res: # Use simpler atom spec for the common case of rotating a side chain. atom_specs = '%s@%s,%s,%s,%s' % (res.string(style='command'), ms_atom2.name, ms_atom.name, fs_atom.name, fs_atom2.name) else: atom_specs = '%s %s %s %s' % ( fs_atom2.string(style='command'), fs_atom.string(style='command'), ms_atom.string(style='command'), ms_atom2.string(style='command')) cmd = 'torsion %s %.2f %s' % (atom_specs, torsion, side) ses = ms_atom.structure.session from chimerax.core.commands import run run(ses, cmd)
def _picked_object(self, pick): warning = lambda txt: self.session.logger.status( "Distance mouse mode: %s" % txt, color = "red") message = self.session.logger.status from chimerax.atomic import PickedAtom, PickedPseudobond from chimerax.core.commands import run if isinstance(pick, PickedAtom): if self._first_atom and self._first_atom.deleted: self._first_atom = None if self._first_atom: if pick.atom == self._first_atom: warning("same atom picked twice") else: a1, a2 = self._first_atom, pick.atom command = "dist %s %s" % (a1.string(style="command line"), a2.string(style="command line")) from chimerax.geometry import distance message("Distance from %s to %s is %g" % (a1, a2, distance(a1.scene_coord, a2.scene_coord))) self._first_atom = None run(self.session, command) else: self._first_atom = pick.atom message("Distance from %s to..." % pick.atom) elif isinstance(pick, PickedPseudobond): if pick.pbond.group.name == "distances": a1, a2 = pick.pbond.atoms command = "~dist %s %s" % (a1.string(style="command line"), a2.string(style="command line")) message("Removing distance") run(self.session, command) else: warning("not a distance") else: warning("no atom/distance picked by mouse click")
def action_host(self, query): # Collect the optional parameters from URL query parameters # and construct a command to execute host, port, conf_name, user_name = self._get_args(query) cmd = self._build_action("host", None, None, None, user_name) from chimerax.core.commands import run run(self.session, cmd)
def _log_swapaa_command(res): if res is None: return ses = res.structure.session cmd = 'swapaa mousemode %s %s' % (res.string(style='command'), res.name) from chimerax.core.commands import run run(ses, cmd)
def run_script(session): from chimerax.core.commands import run from chimerax.core.errors import UserError from chimerax.isolde.atomic.building.build_utils import current_and_possible_disulfides, create_disulfide run(session, 'isolde start', log=False) m = session.isolde.selected_model if m is None: raise UserError('Select a model in ISOLDE first!') current, possible, ambiguous = current_and_possible_disulfides(m) for cys_pair in possible: create_disulfide(*cys_pair) if len(possible): session.logger.info( 'Created disulfide bonds between the following residues: \n{}'. format('; '.join([ '-'.join([ '{}{}{}'.format(c.chain_id, c.number, c.insertion_code) for c in p ]) for p in possible ]))) if len(ambiguous): warn_str = ( 'The following cysteine residues are clustered too close to ' 'automatically assign disulphide-bonded pairs. Please check manually.\n{}' ).format('\n'.join(', '.join([ '{}{}{}'.format(c.chain_id, c.number, c.insertion_code) for c in amb_set ]) for amb_set in ambiguous)) session.logger.warning(warn_str)
def changeModel(self, frame, surf): locs = self.atomLocation[frame] atms = self.atomStruct.atoms atms.coords = locs if surf: ### Need to recalculate the surfce here if self.atomStruct.surfaces() == []: surface(self.session, atoms=self.atomStruct.atoms) else: surfPos = self.surfacePositions[frame] if surfPos is None: self.session.models.remove([self.atomStruct.surfaces()[0]]) surface(self.session, atoms=self.atomStruct.atoms) self.surfacePositions[frame] = self.atomStruct.surfaces( )[0] else: self.session.models.remove([self.atomStruct.surfaces()[0]]) self.atomStruct.add([surfPos]) ### run(self.session, "color #" + self.atomStruct.surfaces()[0].id_string + " fromatoms", log=False) elif self.atomStruct.surfaces() != []: self.session.models.remove([self.atomStruct.surfaces()[0]])
def _opt_cb(opt, updater=updater, converter=converter, ses=session): setting = opt.attr_name val = opt.value if converter: val = converter(val) from chimerax.core.commands import run run(ses, updater % val)
def browse_local(self, job): #for some reason, this doesn't use the native file browser if i just do QFileDialog filename, _ = QFileDialog.getOpenFileName( directory=os.path.abspath(job.scratch_dir)) if filename: run(self.session, "open \"%s\"" % filename)
def select_pick(session, pick, mode='replace'): sel = session.selection from chimerax.core.undo import UndoState undo_state = UndoState("select") sel.undo_add_selected(undo_state, False) if pick is None or (isinstance(pick, list) and len(pick) == 0): if mode == 'replace': from chimerax.core.commands import run run(session, 'select clear') session.logger.status('cleared selection') else: if mode == 'replace': sel.clear() mode = 'add' if isinstance(pick, list): for p in pick: p.select(mode) if pick: session.logger.info('Drag select of %s' % _pick_description(pick)) else: spec = pick.specifier() if mode == 'add' and spec: from chimerax.core.commands import run run(session, 'select %s' % spec) else: pick.select(mode) sel.clear_promotion_history() sel.undo_add_selected(undo_state, True, old_state=False) session.undo.register(undo_state)
def launch_modeller(self): from chimerax.core.commands import run, FileNameArg, StringArg from chimerax.core.errors import UserError alignments = self.alignment_list.value if not alignments: raise UserError("No alignments chosen for modeling") aln_seq_args = [] for aln in alignments: seq_menu = self.seq_menu[aln] seq = seq_menu.value if not seq: raise UserError("No target sequence chosen for alignment %s" % aln.ident) aln_seq_args.append( StringArg.unparse("%s:%d" % (aln.ident, aln.seqs.index(seq) + 1))) from .settings import get_settings settings = get_settings(self.session) run( self.session, "modeller comparative %s multichain %s numModels %d fast %s hetPreserve %s" " hydrogens %s%s waterPreserve %s" % (" ".join(aln_seq_args), repr( settings.multichain).lower(), settings.num_models, repr(settings.fast).lower(), repr(settings.het_preserve).lower(), repr(settings.hydrogens).lower(), " tempPath %s" % FileNameArg.unparse(settings.temp_path) if settings.temp_path else "", repr(settings.water_preserve).lower())) self.delete()
def button_press_cb(event, mode=mode): mname = mode.name if ' ' in mname: mname = '"%s"' % mname from chimerax.core.commands import run run(self.session, 'ui mousemode %s %s' % (self.button_to_bind, mname))
def run_command(self, command): from chimerax.core.commands import run try: run(self.session, command) except Exceptions as e: self.session.info(str(e)) return False return True
def run_hbonds(self): from chimerax.core.commands import run run(self.session, " ".join(self.gui.get_command())) self.session.logger.status( "You can hide/close H-bonds with the Model Panel", secondary=True, color="blue", blank_after=15)
def _create_distance(self): from chimerax.atomic import selected_atoms sel_atoms = selected_atoms(self.session) if len(sel_atoms) != 2: from chimerax.core.errors import UserError raise UserError("Exactly two atoms must be selected!") from chimerax.core.commands import run run(self.session, "distance %s %s" % tuple(a.string(style="command") for a in sel_atoms))
def _show_next(self, step): if not self._viewdockx_running(): return from chimerax.core.commands import run if step > 0: run(self.session, 'viewdockx down') elif step < 0: run(self.session, 'viewdockx up')
def color_pockets(session, n): ''' Color n pockets randomly using named atoms pocket1, pocket2, .... ''' from chimerax.core.colors import random_colors, hex_color from chimerax.core.commands import run for p, color in enumerate(random_colors(n)): run(session, 'color pocket%d %s' % (p + 1, hex_color(color)))
def close(models, session): _mp.self_initiated = True from chimerax.core.models import Model # The 'close' command explicitly avoids closing grouping models where not # all the child models are being closed so that "close ~#1.1" doesn't # close the #1 grouping model. Therefore we need to change the '#!'s # generated by concise_model_spec to just '#'s run(session, "close %s" % concise_model_spec(session, [m for m in models if isinstance(m, Model)]).replace('#!', '#'))
def callback(self, ses): n = _num_selected_objects(ses, self.type) from chimerax.ui.ask import ask if ask(ses, "Really delete %s %s(s)" % (n, self.type), title="Deletion Request") == "no": return from chimerax.core.commands import run run(ses, 'delete %ss sel' % self.type)