def is_default(func, kw, val, special_kw): from inspect import signature sig = signature(func) try: param = sig.parameters[kw] except KeyError: return False if kw in special_kw: pval = special_kw[kw] else: pval = param.default if pval == param.empty: if kw in special_kw: pval = special_kw[kw] else: return False if kw.endswith('color'): from chimerax.core.colors import Color if isinstance(val, Color): cval = val else: cval = Color(val) if not isinstance(pval, Color): pval = Color(param.default) return cval == pval return pval == val
def headerData(self, section, orientation, role=None): if orientation == Qt.Vertical: return QVariant() col = self._item_table._columns[section] if role is None or role == Qt.DisplayRole: if self._item_table._auto_multiline_headers: title = self._make_multiline(col.title) else: title = col.title return title elif role == Qt.TextAlignmentRole: return self._convert_justification(col.header_justification) elif role == Qt.ForegroundRole: if col.color is not None: from chimerax.core.colors import Color if isinstance(col.color, Color): color = col.color else: color = Color(col.color) return QBrush(QColor(*color.uint8x4())) elif role == Qt.ToolTipRole and col.balloon: return col.balloon return QVariant()
def is_default(func, kw, val): from inspect import signature sig = signature(func) param = sig.parameters[kw] if kw.endswith('color'): from chimerax.core.colors import Color if isinstance(val, Color): cval = val else: cval = Color(val) if isinstance(param.default, Color): pval = param.default else: pval = Color(param.default) return cval == pval return param.default == val
def _show_label(self): # Add distance label from chimerax.label.label3d import label from chimerax.core.objects import Objects from chimerax.atomic import Bonds b = Objects(bonds=Bonds([self._link])) text, h = self._label_text_and_height() from chimerax.core.colors import Color label(self.session, objects=b, object_type='bonds', text=text, height=h, color=Color(self._color))
def structure_color(id, bg_color): from chimerax.core.colors import BuiltinColors, distinguish_from, Color try: cname = atomic_color_names[id[0] - 1] model_color = BuiltinColors[cname] if (model_color.rgba[:3] == bg_color[:3]).all(): # force use of another color... raise IndexError("Same as background color") except IndexError: # pick a color that distinguishes from the standard list # as well as white and black and green (highlight), and hope... avoid = [BuiltinColors[cn].rgba[:3] for cn in atomic_color_names] avoid.extend([(0, 0, 0), (0, 1, 0), (1, 1, 1), bg_color[:3]]) model_color = Color(distinguish_from(avoid, num_candidates=7, seed=14)) return model_color
def val_to_str(ses, val, kw): from chimerax.core.commands import \ BoolArg, IntArg, FloatArg, ColorArg, StringArg, SaveFileNameArg if type(val) == bool: return BoolArg.unparse(val, ses) if type(val) == int: return IntArg.unparse(val, ses) if type(val) == float: return FloatArg.unparse(val, ses) if kw.endswith('color'): from chimerax.core.colors import Color return ColorArg.unparse(Color(rgba=val), ses) if kw == 'save_file': return SaveFileNameArg.unparse(val, ses) return StringArg.unparse(str(val), ses)
def _update_connections(self): cxy_list = [self._scene_xy(m.xy) for m in self._markers] scene = self._scene pen = QPen( QColor(*[ int(255 * chan + 0.5) for chan in Color(self.connect_color).rgba[:3] ])) items = [] for k in range(len(cxy_list) - 1): x0, y0 = cxy_list[k] x1, y1 = cxy_list[k + 1] item = scene.addLine(x0, y0, x1, y1, pen=pen) items.append(item) for item in self._connector_items: scene.removeItem(item) self._connector_items = items
def get_value(self): from chimerax.core.colors import Color return Color(rgba=super().value)
def _set_drawing_color(self): from chimerax.core.colors import contrast_with, Color import numpy color = numpy.array([0,0,0,0.5], numpy.float32) color[:3] = contrast_with(self.view.background_color) self._drawing.color = Color(color).uint8x4()
def _rgba(self, color_info): if color_info is None: color_info = self.new_color return Color(color_info).rgba
def _cmd(session, test_atoms, name, hbond_allowance, overlap_cutoff, test_type, color, radius, *, attr_name=defaults["attr_name"], bond_separation=defaults["bond_separation"], continuous=False, dashes=None, distance_only=None, inter_model=True, inter_submodel=False, intra_model=True, intra_mol=defaults["intra_mol"], intra_res=defaults["intra_res"], log=defaults["action_log"], make_pseudobonds=defaults["action_pseudobonds"], naming_style=None, res_separation=None, restrict="any", reveal=False, save_file=None, set_attrs=defaults["action_attr"], select=defaults["action_select"], show_dist=False, summary=True): from chimerax.core.errors import UserError if test_atoms is None: from chimerax.atomic import AtomicStructure, AtomicStructures test_atoms = AtomicStructures([ s for s in session.models if isinstance(s, AtomicStructure) ]).atoms if not test_atoms: raise UserError("No atoms match given atom specifier") from chimerax.core.colors import Color if color is not None and not isinstance(color, Color): color = Color(rgba=color) from chimerax.atomic import get_triggers ongoing = False if continuous: if set_attrs or save_file != None or log: raise UserError( "log/setAttrs/saveFile not allowed with continuous detection") if getattr(session, _continuous_attr, None) == None: from inspect import getargvalues, currentframe, getfullargspec arg_names, fArgs, fKw, frame_dict = getargvalues(currentframe()) arg_spec = getfullargspec(_cmd) args = [frame_dict[an] for an in arg_names[:len(arg_spec.args)]] kw = {k: frame_dict[k] for k in arg_names[len(arg_spec.args):]} call_data = (args, kw) def changes_cb(trig_name, changes, session=session, call_data=call_data): s_reasons = changes.atomic_structure_reasons() a_reasons = changes.atom_reasons() if 'position changed' in s_reasons \ or 'active_coordset changed' in s_reasons \ or 'coord changed' in a_reasons \ or 'alt_loc changed' in a_reasons: args, kw = call_data if not args[1]: # all atoms gone delattr(session, _continuous_attr) from chimerax.core.triggerset import DEREGISTER return DEREGISTER _cmd(*tuple(args), **kw) setattr(session, _continuous_attr, get_triggers().add_handler('changes', changes_cb)) else: ongoing = True elif getattr(session, _continuous_attr, None) != None: get_triggers().remove_handler(getattr(session, _continuous_attr)) delattr(session, _continuous_attr) from .clashes import find_clashes clashes = find_clashes(session, test_atoms, attr_name=attr_name, bond_separation=bond_separation, clash_threshold=overlap_cutoff, distance_only=distance_only, hbond_allowance=hbond_allowance, inter_model=inter_model, inter_submodel=inter_submodel, intra_model=intra_model, intra_res=intra_res, intra_mol=intra_mol, res_separation=res_separation, restrict=restrict) if select: session.selection.clear() for a in clashes.keys(): a.selected = True # if relevant, put the test_atoms in the first column if restrict == "both": output_grouping = set() else: output_grouping = test_atoms test_type = "distances" if distance_only else test_type info = (overlap_cutoff, hbond_allowance, bond_separation, intra_res, intra_mol, clashes, output_grouping, test_type, res_separation) if log: import io buffer = io.StringIO() buffer.write("<pre>") _file_output(buffer, info, naming_style) buffer.write("</pre>") session.logger.info(buffer.getvalue(), is_html=True) if save_file is not None: _file_output(save_file, info, naming_style) if summary: if clashes: total = 0 for clash_list in clashes.values(): total += len(clash_list) session.logger.status("%d %s" % (total / 2, test_type), log=not ongoing) else: session.logger.status("No %s" % test_type, log=not ongoing) if not (set_attrs or make_pseudobonds or reveal): _xcmd(session, name) return clashes from chimerax.atomic import all_atoms if restrict == "both": attr_atoms = test_atoms elif restrict in ("any", "cross"): if inter_model: attr_atoms = all_atoms(session) else: attr_atoms = test_atoms.unique_structures.atoms else: from chimerax.atomic import concatenate attr_atoms = concatenate([test_atoms, restrict], remove_duplicates=True) from chimerax.atomic import Atoms clash_atoms = Atoms([a for a in attr_atoms if a in clashes]) if set_attrs: # delete the attribute in _all_ atoms... for a in all_atoms(session): if hasattr(a, attr_name): delattr(a, attr_name) for a in clash_atoms: clash_vals = list(clashes[a].values()) clash_vals.sort() setattr(a, attr_name, clash_vals[-1]) if reveal: # display sidechain or backbone as appropriate for undisplayed atoms reveal_atoms = clash_atoms.filter(clash_atoms.displays == False) reveal_residues = reveal_atoms.unique_residues sc_rv_atoms = reveal_atoms.filter(reveal_atoms.is_side_chains == True) if sc_rv_atoms: sc_residues = sc_rv_atoms.unique_residues sc_res_atoms = sc_residues.atoms sc_res_atoms.filter( sc_res_atoms.is_side_chains == True).displays = True reveal_residues = reveal_residues - sc_residues bb_rv_atoms = reveal_atoms.filter(reveal_atoms.is_backbones() == True) if bb_rv_atoms: bb_residues = bb_rv_atoms.unique_residues bb_res_atoms = bb_residues.atoms bb_res_atoms.filter( bb_res_atoms.is_backbones() == True).displays = True reveal_residues = reveal_residues - bb_residues # also reveal non-polymeric atoms reveal_residues.atoms.displays = True if make_pseudobonds: if len(attr_atoms.unique_structures) > 1: pbg = session.pb_manager.get_group(name) else: pbg = attr_atoms[0].structure.pseudobond_group(name) pbg.clear() pbg.radius = radius if color is not None: pbg.color = color.uint8x4() if dashes is not None: pbg.dashes = dashes seen = set() for a in clash_atoms: seen.add(a) for clasher in clashes[a].keys(): if clasher in seen: continue pbg.new_pseudobond(a, clasher) if show_dist: session.pb_dist_monitor.add_group(pbg) else: session.pb_dist_monitor.remove_group(pbg) if pbg.id is None: session.models.add([pbg]) else: _xcmd(session, name) return clashes