Exemplo n.º 1
0
 def _update_graphics_if_needed(self, trigger_name, changes):
     if not self.visible:
         return
     changes = changes[1]
     update_needed = False
     if (self._track_whole_model):
         '''
         Need to update the set of ramas if atoms are added. Deletions will
         take care of themselves.
         '''
         created = changes.created_atoms()
         if len(created):
             from chimerax.atomic import Residue
             # Only need to update if the additions are non-hydrogen protein atoms
             ur = created[created.element_names !='H'].unique_residues
             if any(ur.polymer_types == Residue.PT_AMINO):
                 # Trigger rebuild of rama array and graphics update
                 self.track_whole_model = True
                 # self._prepare_ca_display()
                 return
     reasons = changes.atom_reasons()
     if 'coord changed' in reasons:
         update_needed = True
     if 'display changed' in reasons or 'hide changed' in reasons:
         # self._prepare_ca_display()
         self._update_visible_ramas()
         update_needed = True
     if 'selected changed' in reasons:
         update_needed = True
     # if 'color changed' in reasons:
     #     update_needed = True
     if update_needed:
         from chimerax.atomic import get_triggers
         get_triggers().add_handler('changes done', self.update_graphics)
Exemplo n.º 2
0
 def _update_graphics_if_needed(self, trigger_name, changes):
     if not self.visible:
         return
     changes = changes[1]
     update_needed = False
     if (self._track_whole_model):
         '''
         Need to update the set of rotamers if atoms are added. Deletions will
         take care of themselves.
         '''
         created = changes.created_atoms()
         if len(created):
             # Only need to update if we've added new non-hydrogen protein atoms
             from chimerax.atomic import Residue
             ur = created[created.element_names!='H'].unique_residues
             if sum(ur.polymer_types==Residue.PT_AMINO):
                 r = self._selected_residues = self._atomic_structure.residues
                 self._selected_rotamers = self._mgr.get_rotamers(r)
                 update_needed = True
     if changes.num_deleted_atoms():
         update_needed = True
     reasons = changes.atom_reasons()
     if 'coord changed' in reasons:
         update_needed = True
     if 'display changed' in reasons or 'hide changed' in reasons:
         update_needed = True
     if (update_needed):
         from chimerax.atomic import get_triggers
         get_triggers().add_handler('changes done', self.update_graphics)
Exemplo n.º 3
0
 def delete(self):
     self.region_browser.destroy()
     self.seq_canvas.destroy()
     self.alignment.detach_viewer(self)
     for seq in self.alignment.seqs:
         seq.triggers.remove_handler(self._seq_rename_handlers[seq])
     from chimerax.atomic import get_triggers
     get_triggers().remove_handler(self._atomic_changes_handler)
     ToolInstance.delete(self)
Exemplo n.º 4
0
 def delete_rotation(self, rotater):
     del self.bond_rotaters[rotater.ident]
     rotation = rotater.rotation
     rotation.rotaters.remove(rotater)
     if not rotation.rotaters:
         del self.bond_rotations[rotation.bond]
         if not self.bond_rotations:
             from chimerax.atomic import get_triggers
             get_triggers().remove_handler(self._handler_ID)
     if not rotater.one_shot:
         self.triggers.activate_trigger(self.DELETED, rotater)
Exemplo n.º 5
0
 def delete_all_rotations(self):
     for rotater in self.bond_rotaters.values():
         self.triggers.activate_trigger(self.DELETED, rotater)
     if self.bond_rotations:
         from chimerax.atomic import get_triggers
         get_triggers().remove_handler(self._handler_ID)
         for rotation in self.bond_rotations.values():
             # break reference loops
             rotation.rotaters =  []
         self.bond_rotations.clear()
         self.bond_rotaters.clear()
Exemplo n.º 6
0
 def _mmap_mod_cb(self, trig_name, match_map):
     if len(match_map) == 0:
         self.disassociate(self._sseq_to_chain[match_map.struct_seq],
                           demotion=True)
         del self._sseq_to_chain[match_map.struct_seq]
     else:
         if not self._modified_mmaps:
             from chimerax.atomic import get_triggers
             get_triggers().add_handler("changes done",
                                        self._atomic_changes_done)
         self._modified_mmaps.append(match_map)
Exemplo n.º 7
0
 def _set_auto_update(self, enable):
     h = self._auto_update_handler
     if enable and h is None:
         from chimerax.atomic import get_triggers
         t = get_triggers()
         self._auto_update_handler = t.add_handler('changes',
                                                   self._atoms_changed)
         if self.vertices is not None:
             self._recompute_shape()
     elif not enable and h:
         from chimerax.atomic import get_triggers
         t = get_triggers()
         t.remove_handler(h)
         self._auto_update_handler = None
Exemplo n.º 8
0
def _xcmd(session, group_name):
    if getattr(session, _continuous_attr, None) != None:
        from chimerax.atomic import get_triggers
        get_triggers().remove_handler(getattr(session, _continuous_attr))
        delattr(session, _continuous_attr)
    pbg = session.pb_manager.get_group(group_name, create=False)
    pbgs = [pbg] if pbg else []
    from chimerax.atomic import AtomicStructure
    for s in [m for m in session.models if isinstance(m, AtomicStructure)]:
        pbg = s.pseudobond_group(group_name, create_type=None)
        if pbg:
            pbgs.append(pbg)
    if pbgs:
        session.models.close(pbgs)
Exemplo n.º 9
0
    def __init__(self,
                 session,
                 groups,
                 contacts,
                 interface_residue_area_cutoff=5):

        # Create matplotlib panel
        title = '%d Chains %d Contacts' % (len(groups), len(contacts))
        Graph.__init__(self,
                       session,
                       groups,
                       contacts,
                       tool_name="Chain Contacts",
                       title=title)

        self.groups = groups
        self.contacts = contacts
        self.interface_residue_area_cutoff = interface_residue_area_cutoff

        # Show contact areas less than half maximum as dotted lines.
        small_area = 0.5 * max(c.buried_area for c in contacts)
        for c in contacts:
            if c.buried_area < small_area:
                c.style = 'dotted'
                c.width = 2

        self.draw_graph()

        # When group is undisplayed update its node color.
        from chimerax import atomic
        self._handler = atomic.get_triggers(session).add_handler(
            'changes', self._atom_display_change)
Exemplo n.º 10
0
    def __init__(self, session, structure, pause_frames = 1, movie_framerate = 25,
                 steady_atoms = None, compute_ss = False):

        self.structure = structure

        title = 'Coordinate sets %s (%d)' % (structure.name, structure.num_coordsets)
        csids = structure.coordset_ids
        id_start, id_end = min(csids), max(csids)
        self.coordset_ids = set(csids)
        Slider.__init__(self, session, 'Model Series', 'Model', title, value_range = (id_start, id_end),
                        pause_frames = pause_frames, pause_when_recording = True,
                        movie_framerate = movie_framerate)

        from .coordset import CoordinateSetPlayer
        self._player = CoordinateSetPlayer(structure, id_start, id_end, istep = 1,
                                           pause_frames = pause_frames, loop = 1,
                                           compute_ss = compute_ss, steady_atoms = steady_atoms)
        self.update_value(structure.active_coordset_id)

        from chimerax import atomic
        t = atomic.get_triggers(session)
        self._coordset_change_handler = t.add_handler('changes', self.coordset_change_cb)
        
        from chimerax.core.models import REMOVE_MODELS
        self._model_close_handler = session.triggers.add_handler(REMOVE_MODELS, self.models_closed_cb)

        if not hasattr(session, '_coord_set_sliders'):
            session._coord_set_sliders = set()
        session._coord_set_sliders.add(self)
Exemplo n.º 11
0
    def __init__(self, session):
        Model.__init__(self, 'labels', session)

        self.on_top = True  # Should labels always appear above other graphics
        self._window_size = session.main_view.window_size

        self._labels = []  # list of ObjectLabel
        self._object_label = {
        }  # Map object (Atom, Residue, Pseudobond, Bond) to ObjectLabel
        self._num_pixel_labels = 0  # Number of labels sized in pixels.

        t = session.triggers
        self._update_graphics_handler = t.add_handler(
            'graphics update', self._update_graphics_if_needed)
        self._model_display_handler = t.add_handler(
            'model display changed', self._model_display_changed)
        from chimerax.core.core_settings import settings as core_settings
        self._background_color_handler = core_settings.triggers.add_handler(
            'setting changed', self._background_changed_cb)

        from chimerax.atomic import get_triggers
        ta = get_triggers()
        self._structure_change_handler = ta.add_handler(
            'changes', self._structure_changed)

        self.use_lighting = False
        Model.set_color(self,
                        (255, 255, 255, 255))  # Do not modulate texture colors

        self._texture_width = 2048  # Pixels.
        self._texture_needs_update = True  # Has text, color, size, font changed.
        self._positions_need_update = True  # Has label position changed relative to atom?
        self._visibility_needs_update = True  # Does an atom hide require a label to hide?
Exemplo n.º 12
0
    def disassociate(self, sseq, *, reassoc=False, demotion=False):
        if sseq not in self.associations or self._in_destroy:
            return

        if self.intrinsic:
            self.session.alignments.destroy_alignment(self)
            return
        aseq = self.associations[sseq]
        match_map = aseq.match_maps[sseq]
        del aseq.match_maps[sseq]
        del self.associations[sseq]
        match_map.mod_handler.remove()
        if reassoc:
            return
        if not demotion:
            # if the structure seq hasn't been demoted/destroyed, log the disassociation
            struct = sseq.structure
            struct_name = struct.name
            if '.' in struct.id_string:
                # ensemble
                struct_name += " (" + struct.id_string + ")"
            self.session.logger.info("Disassociated %s %s from %s" %
                                     (struct_name, sseq.name, aseq.name))
        # delay notifying the observers until all chain demotions/deletions have been received
        num_unknown = 0
        structures = set()
        for sseq in self.associations:
            try:
                structures.add(sseq.structure)
            except AttributeError:
                # demoted
                num_unknown += 1
        data = {
            'match map': match_map,
            'num remaining associations': len(self.associations),
            'max previous structures': len(structures) + num_unknown,
            'num remaining structures': len(structures)
        }

        def _delay_disassoc(_, __, data=data):
            self._notify_observers(self.NOTE_DEL_ASSOC, data)
            from chimerax.core.triggerset import DEREGISTER
            return DEREGISTER

        from chimerax import atomic
        atomic.get_triggers().add_handler('changes done', _delay_disassoc)
Exemplo n.º 13
0
 def __init__(self, session, bundle_info):
     self.session = session
     self.monitored_groups = set()
     self.update_callbacks = {}
     self._distances_shown = True
     from chimerax.atomic import get_triggers
     triggers = get_triggers()
     triggers.add_handler("changes", self._changes_handler)
     self._already_restored = set()
Exemplo n.º 14
0
    def close(self):
        self.session.triggers.remove_handler(self._show_rot_vec)
        global_triggers = get_triggers()
        global_triggers.remove_handler(self._changes)

        for model in self.session.models.list(type=Generic3DModel):
            if model.name == "rotation vector":
                model.delete()

        return super().close()
Exemplo n.º 15
0
 def __init__(self, alignment, *args, **kw):
     from math import log
     self.scaling = log(0.5) / (-3.0)
     super().__init__(alignment, *args, **kw)
     from chimerax.atomic import get_triggers
     self.handlers = [
         self.settings.triggers.add_handler('setting changed',
                                            self._setting_changed_cb),
         get_triggers().add_handler('changes', self._atomic_changes_cb)
     ]
     self._set_name()
Exemplo n.º 16
0
 def _ses_restore(self, data):
     self.clear()
     if 'bond_rots' in data:
         # old, non-backwards compatible, session data
         if data['bond_rots']:
             self.session.logger.warning('Bond-rotation data in session is obsolete and not restorable;'
                 " skipping")
         return
     self.bond_rotations = data['rotations']
     self.bond_rotaters = data['rotaters']
     if self.bond_rotations:
         from chimerax.atomic import get_triggers
         self._handler_ID = get_triggers().add_handler('changes', self._changes_cb)
Exemplo n.º 17
0
    def new_rotation(self, bond, ident=None, move_smaller_side=True, one_shot=True):
        """Create bond rotation for 'bond'

        Parameters
        ----------
        bond : Bond
            Bond to rotate
        ident: an integer or None
            Number used to refer to bond rotation in commands.  If None, automatically assign
            one.
        move_smaller_side: bool
            If True, move the "smaller" side (side with fewer atoms attached) when the
            bond rotation moves.  Otherwise move the bigger side.
        one_shot: bool
            True if the rotation is going to be used to change the torsion and then immediately
            deleted -- so don't bother firing triggers.

        Returns the created BondRotater
        """
        if ident is None:
            ident = 1
            while ident in self.bond_rotaters:
                ident += 1
        elif ident in self.bond_rotaters:
            raise BondRotationError("Bond rotation identifier %s already in use" % ident)

        try:
            moving_side = bond.smaller_side
        except ValueError:
            raise BondRotationError("Bond %s is part of a ring/cycle and cannot be rotated" % bond)
        if not move_smaller_side:
            moving_side = bond.other_atom(moving_side)

        if not self.bond_rotations:
            from chimerax.atomic import get_triggers
            self._handler_ID = get_triggers().add_handler('changes', self._changes_cb)

        if bond in self.bond_rotations:
            rotation = self.bond_rotations[bond]
        else:
            from .bond_rot import BondRotation
            rotation = BondRotation(self.session, bond)
        self.bond_rotations[bond] = rotation

        rotater = rotation.new_rotater(ident, moving_side, one_shot)
        self.bond_rotaters[ident] = rotater

        if not one_shot:
            self.triggers.activate_trigger(self.CREATED, rotater)
            self.session.logger.status("Bond rotation identifier is %s" % ident, log=True)
        return rotater
Exemplo n.º 18
0
    def delete(self):
        from chimerax import atomic
        t = atomic.get_triggers(self.session)
        t.remove_handler(self._coordset_change_handler)
        self._coordset_change_handler = None

        self.session._coord_set_sliders.remove(self)

        t = self.session.triggers
        t.remove_handler(self._model_close_handler)
        self._model_close_handler = None

        super().delete()
        self.structure = None
Exemplo n.º 19
0
 def __init__(self, session, base_residue, rotamers):
     self.init_state_manager(session, "residue rotamers")
     self.session = session
     self.base_residue = base_residue
     self.rotamers = list(
         rotamers)  # don't want auto-shrinking of a Collection
     self.group = session.models.add_group(
         rotamers,
         name="%s rotamers" % base_residue.string(omit_structure=True),
         parent=base_residue.structure)
     from chimerax.atomic import get_triggers
     self.handler = get_triggers().add_handler('changes', self._changes_cb)
     from chimerax.core.triggerset import TriggerSet
     self.triggers = TriggerSet()
     self.triggers.add_trigger('fewer rotamers')  # but not zero
     self.triggers.add_trigger('self destroyed')
Exemplo n.º 20
0
    def __init__(self, session, name):
        super().__init__(session, name)

        self.tool_window = MainToolWindow(self)

        self.settings = _PrecisionRotateSettings(session, name)

        self.bonds = {}
        self.bond_centers = {}
        self.groups = {}
        self.perpendiculars = {}
        self.perp_centers = {}
        self.manual_center = {}

        self._build_ui()

        self._show_rot_vec = self.session.triggers.add_handler(
            SELECTION_CHANGED, self.show_rot_vec)
        global_triggers = get_triggers()
        self._changes = global_triggers.add_handler("changes done",
                                                    self.show_rot_vec)

        self.show_rot_vec()
Exemplo n.º 21
0
    def _finalize_init(self, alignment):
        """TODO
        from chimera import triggerSet
        self.triggers = triggerSet.TriggerSet()
        self.triggers.addTrigger(ADD_ASSOC)
        self.triggers.addTrigger(DEL_ASSOC)
        self.triggers.addTrigger(MOD_ASSOC)
        self.triggers.addHandler(ADD_ASSOC, self._fireModAssoc, None)
        self.triggers.addHandler(DEL_ASSOC, self._fireModAssoc, None)
        self.triggers.addTrigger(ADD_SEQS)
        self.triggers.addTrigger(PRE_DEL_SEQS)
        self.triggers.addTrigger(DEL_SEQS)
        self.triggers.addTrigger(ADDDEL_SEQS)
        self.triggers.addTrigger(SEQ_RENAMED)
        self.triggers.addHandler(ADD_SEQS, self._fireAddDelSeq, None)
        self.triggers.addHandler(DEL_SEQS, self._fireAddDelSeq, None)
        self.triggers.addHandler(ADDDEL_SEQS, self._fireModAlign, None)
        self.triggers.addTrigger(MOD_ALIGN)
        self.associations = {}
        self._resAttrs = {}
        self._edited = False

        from common import getStaticSeqs
        seqs, fileMarkups, fileAttrs = getStaticSeqs(fileNameOrSeqs, fileType=fileType)
        self.seqs = seqs
        """
        self.alignment = alignment
        from . import subcommand_name
        alignment.attach_viewer(self, subcommand_name=subcommand_name)
        from . import settings
        self.settings = settings.init(self.session)
        """
        from SeqCanvas import shouldWrap
        if numberingDisplay:
            defaultNumbering = numberingDisplay
        else:
            defaultNumbering = (True,
                not shouldWrap(len(seqs), self.prefs))
        self.numberingsStripped = False
        if getattr(seqs[0], 'numberingStart', None) is None:
            # see if sequence names imply numbering...
            startInfo = []
            for seq in seqs:
                try:
                    name, numbering = seq.name.rsplit('/',1)
                except ValueError:
                    break
                try:
                    start, end = numbering.split('-')
                except ValueError:
                    start = numbering
                try:
                    startInfo.append((name, int(start)))
                except ValueError:
                    break
            if len(startInfo) == len(seqs):
                self.numberingsStripped = True
                for i, seq in enumerate(seqs):
                    seq.name, seq.numberingStart = \
                                startInfo[i]
            else:
                for seq in seqs:
                    if hasattr(seq, 'residues'):
                        for i, r in enumerate(seq.residues):
                            if r:
                                seq.numberingStart = r.id.position - 1
                                break
                        else:
                            seq.numberingStart = 1
                    else:
                        seq.numberingStart = 1
                if not numberingDisplay:
                    defaultNumbering = (False, False)

        self._defaultNumbering = defaultNumbering
        self.fileAttrs = fileAttrs
        self.fileMarkups = fileMarkups
        if not title:
            if isinstance(fileNameOrSeqs, basestring):
                title = os.path.split(fileNameOrSeqs)[1]
            else:
                title = "Sequence Viewer"
        self.title = title
        self.autoAssociate = autoAssociate
        self.quitCB = quitCB
        self.sessionSave = sessionSave
        self._runModellerWSList = []
        self._runModellerLocalList = []
        self._realignmentWSJobs = {'self': [], 'new': []}
        self._blastAnnotationServices = {}
        ModelessDialog.__init__(self)
        """
        words = self.alignment.description.split()
        capped_words = []
        for word in words:
            if word.islower() and word.isalpha():
                capped_words.append(word.capitalize())
            else:
                capped_words.append(word)
        self.display_name = " ".join(
            capped_words) + " [ID: %s]" % self.alignment.ident
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self,
                                          close_destroys=True,
                                          statusbar=True)
        self.tool_window._dock_widget.setMouseTracking(True)
        self.tool_window.fill_context_menu = self.fill_context_menu
        self.status = self.tool_window.status
        parent = self.tool_window.ui_area
        parent.setMouseTracking(True)
        """TODO
        # SeqCanvas will use these...
        leftNums, rightNums = self._defaultNumbering
        self.leftNumberingVar = Tkinter.IntVar(parent)
        self.leftNumberingVar.set(leftNums)
        self.rightNumberingVar = Tkinter.IntVar(parent)
        self.rightNumberingVar.set(rightNums)

        """
        from .seq_canvas import SeqCanvas
        self.seq_canvas = SeqCanvas(parent, self, self.alignment)
        if self.alignment.associations:
            # There are pre-existing associations, show them
            for aseq in self.alignment.seqs:
                if aseq.match_maps:
                    self.seq_canvas.assoc_mod(aseq)
        from .region_browser import RegionBrowser
        rb_window = self.tool_window.create_child_window("Regions",
                                                         close_destroys=False)
        self.region_browser = RegionBrowser(rb_window, self.seq_canvas)
        self._seq_rename_handlers = {}
        for seq in self.alignment.seqs:
            self._seq_rename_handlers[seq] = seq.triggers.add_handler(
                "rename", self.region_browser._seq_renamed_cb)
            if seq.match_maps:
                self._update_errors_gaps(seq)
        if self.alignment.intrinsic:
            self.show_ss(True)
            self.status("Helices/strands depicted in gold/green")
        """TODO
        if self.fileMarkups:
            from HeaderSequence import FixedHeaderSequence
            headers = []
            for name, val in self.fileMarkups.items():
                headers.append(
                    FixedHeaderSequence(name, self, val))
            self.addHeaders(headers)
        self.prefDialog = PrefDialog(self)
        top = parent.winfo_toplevel()
        cb = lambda e, rb=self.regionBrowser: rb.deleteRegion(
                                rb.curRegion())
        top.bind('<Delete>', cb)
        top.bind('<BackSpace>', cb)
        self.menuBar = Tkinter.Menu(top, type="menubar", tearoff=False)
        top.config(menu=self.menuBar)

        self.fileMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="File", menu=self.fileMenu)
        self.fileMenu.add_command(label="Save As...", command=self.save)
        self.epsDialog = None
        self.fileMenu.add_command(label="Save EPS...",
                        command=self._showEpsDialog)
        self.fileMenu.add_command(label="Save Association Info...",
            state='disabled', command=self._showAssocInfoDialog)
        self.fileMenu.add_separator()
        self.fileMenu.add_command(label="Load SCF/Seqsel File...",
                command=lambda: self.loadScfFile(None))
        self.fileMenu.add_command(label="Load Color Scheme...",
                    command=self._showColorSchemeDialog)
        self.fileMenu.add_separator()
        self.fileMenu.add_command(label="Hide", command=self.Hide)
        self.fileMenu.add_command(label="Quit", command=self.Quit)
        if parent == dialogParent:
            # if we're not part of a custom interface,
            # override the window-close button to quit, not hide
            top.protocol('WM_DELETE_WINDOW', self.Quit)

        self.editMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Edit", menu=self.editMenu)
        self.editMenu.add_command(label="Copy Sequence...",
                    command=self._showCopySeqDialog)
        self.editMenu.add_command(label="Reorder Sequences...",
                    command=self._showReorderDialog)
        self.editMenu.add_command(label="Insert All-Gap Columns...",
                    command=self._showInsertGapDialog)
        self.editMenu.add_command(label="Delete Sequences/Gaps...",
                    command=self._showDelSeqsGapsDialog)
        self.editMenu.add_command(label="Add Sequence...",
                    command=self._showAddSeqDialog)
        self.editMenu.add_command(label="Realign Sequences...",
                    command=self._showRealignmentDialog)
        self.editMenu.add_command(label="Alignment Annotations...",
                    command=self._showAlignAttrDialog)
        self.editMenu.add_command(label="Edit Sequence Name...",
                    command=self._showSeqNameEditDialog)
        self.editMenu.add_command(label="Show Editing Keys...",
                    command=self._showEditKeysDialog)
        self.editMenu.add_command(label=u"Region \N{RIGHTWARDS ARROW} New Window",
                    command=self.exportActiveRegion)
        self.editMenu.add_separator()
        self.editMenu.add_command(label="Find Subsequence...",
                    command=self._showFindDialog)
        self.editMenu.add_command(label="Find Regular Expression...",
                    command=self._showRegexDialog)
        self.editMenu.add_command(label="Find PROSITE Pattern...",
                    command=self._showPrositeDialog)
        self.editMenu.add_command(label="Find Sequence Name...",
                    command=self._showFindSeqNameDialog)

        self.structureMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Structure",
                            menu=self.structureMenu)
        self.structureMenu.add_command(label="Load Structures",
                        command=self._loadStructures)
        """
        """
        self.alignDialog = self.assessDialog = self.findDialog = None
        self.prositeDialog = self.regexDialog = None
        self.associationsDialog = self.findSeqNameDialog = None
        self.saveHeaderDialog = self.alignAttrDialog = None
        self.assocInfoDialog = self.loadHeaderDialog = None
        self.identityDialog = self.colorSchemeDialog = None
        self.modellerHomologyDialog = self.fetchAnnotationsDialog = None
        self.treeDialog = self.reorderDialog = self.blastPdbDialog = None
        self.delSeqsGapsDialog = self.insertGapDialog = None
        self.addSeqDialog = self.numberingsDialog = None
        self.editKeysDialog = self.copySeqDialog = None
        self.modellerLoopsDialog = self.seqNameEditDialog = None
        self.realignDialog = None
        self.structureMenu.add_command(label="Match...",
                state='disabled', command=self._showAlignDialog)
        
        self.structureMenu.add_command(label="Assess Match...",
            state='disabled', command=self._showAssessDialog)

        if len(self.seqs) <= 1:
            state = "disabled"
        else:
            state = "normal"
        self.structureMenu.add_command(label="Modeller (homology)...",
            state=state, command=self._showModellerHomologyDialog)
        self.structureMenu.add_command(label=self.MODEL_LOOPS_MENU_TEXT,
            state="disabled", command=self._showModellerLoopsDialog)

        if chimera.openModels.list(modelTypes=[chimera.Molecule]):
            assocState = 'normal'
        else:
            assocState = 'disabled'
        self.structureMenu.add_command(label="Associations...",
            state=assocState, command=self._showAssociationsDialog)
        self.ssMenu = Tkinter.Menu(self.structureMenu)
        self.structureMenu.add_cascade(label="Secondary Structure",
                            menu=self.ssMenu)
        self.showSSVar = Tkinter.IntVar(parent)
        self.showSSVar.set(False)
        self.showPredictedSSVar = Tkinter.IntVar(parent)
        self.showPredictedSSVar.set(False)
        self.ssMenu.add_checkbutton(label="show actual",
            variable=self.showSSVar, command=lambda s=self: s.showSS(show=None))
        self.ssMenu.add_checkbutton(label="show predicted",
            variable=self.showPredictedSSVar,
            command=lambda s=self: s.showSS(show=None, ssType="predicted"))
        # actual SS part of MOD_ASSOC handler...
        self._predSSHandler = self.triggers.addHandler(ADD_SEQS,
            lambda a1, a2, a3, s=self:
            s.showSS(show=None, ssType="predicted"), None)
        """
        from chimerax.atomic import get_triggers
        self._atomic_changes_handler = get_triggers().add_handler(
            "changes", self._atomic_changes_cb)
        """TODO
        self.structureMenu.add_command(state='disabled',
                label="Select by Conservation...",
                command=lambda: self._doByConsCB("Select"))
        self.structureMenu.add_command(state='disabled',
                label="Render by Conservation...",
                command=lambda: self._doByConsCB("Render"))
        self.structureMenu.add_command(label="Expand Selection to"
                " Columns", state=assocState,
                command=self.expandSelectionByColumns)
        self._modAssocHandlerID = self.triggers.addHandler(
                    MOD_ASSOC, self._modAssocCB, None)

        self.headersMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Headers", menu=self.headersMenu)
        self.headersMenu.add_command(label="Save...",
            command=self._showSaveHeaderDialog)
        self.headersMenu.add_command(label="Load...",
                    command=self._showLoadHeaderDialog)
        self.headersMenu.add_separator()
        for trig in [ADD_HEADERS,DEL_HEADERS,SHOW_HEADERS,HIDE_HEADERS,
                                MOD_ALIGN]:
            self.triggers.addHandler(trig,
                        self._rebuildHeadersMenu, None)
        self._rebuildHeadersMenu()

        self.numberingsMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Numberings",
                        menu=self.numberingsMenu)
        self.showRulerVar = Tkinter.IntVar(self.headersMenu)
        self.showRulerVar.set(
                len(self.seqs) > 1 and self.prefs[SHOW_RULER_AT_STARTUP])
        self.numberingsMenu.add_checkbutton(label="Overall Alignment",
                        selectcolor="black",
                        variable=self.showRulerVar,
                        command=self.setRulerDisplay)
        self.numberingsMenu.add_separator()
        self.numberingsMenu.add_checkbutton(
                    label="Left Sequence",
                    selectcolor="black",
                    variable=self.leftNumberingVar,
                    command=self.setLeftNumberingDisplay)
        self.numberingsMenu.add_checkbutton(
                    label="Right Sequence",
                    selectcolor="black",
                    variable=self.rightNumberingVar,
                    command=self.setRightNumberingDisplay)
        self.numberingsMenu.add_command(
                    label="Adjust Sequence Numberings...",
                    command = self._showNumberingsDialog)

        self.treeMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Tree", menu=self.treeMenu)
        self.treeMenu.add_command(label="Load...",
                    command=self._showTreeDialog)
        self.showTreeVar = Tkinter.IntVar(self.menuBar)
        self.showTreeVar.set(True)
        self.treeMenu.add_checkbutton(label="Show Tree",
            selectcolor="black",
            variable=self.showTreeVar, command=self._showTreeCB,
            state='disabled')
        self.treeMenu.add_separator()
        self.treeMenu.add_command(label="Extract Subalignment",
            state="disabled", command=self.extractSubalignment)

        self.infoMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Info", menu=self.infoMenu)
        if len(self.seqs) == 1:
            state = "disabled"
        else:
            state = "normal"
        self.infoMenu.add_command(label="Percent Identity...",
                state=state, command=self._showIdentityDialog)
        self.infoMenu.add_command(label="Region Browser",
                    command=self.regionBrowser.enter)
        self.infoMenu.add_command(label="Blast Protein...",
                    command=self._showBlastPdbDialog)
        self.infoMenu.add_command(label="UniProt/CDD Annotations...",
                    command=self._showFetchAnnotationsDialog)
        self.preferencesMenu = Tkinter.Menu(self.menuBar)
        self.menuBar.add_cascade(label="Preferences",
                        menu=self.preferencesMenu)

        from chimera.tkgui import aquaMenuBar
        aquaMenuBar(self.menuBar, parent, row = 0, columnspan = 4)

        for tab in self.prefDialog.tabs:
            self.preferencesMenu.add_command(label=tab,
                command=lambda t=tab: [self.prefDialog.enter(),
                self.prefDialog.notebook.selectpage(t)])

        self.status("Mouse drag to create region (replacing current)\n",
            blankAfter=30, followTime=40, followWith=
            "Shift-drag to add to current region\n"
            "Control-drag to add new region")
        self._addHandlerID = chimera.openModels.addAddHandler(
                        self._newModelsCB, None)
        self._removeHandlerID = chimera.openModels.addRemoveHandler(
                        self._closeModelsCB, None)
        self._closeSessionHandlerID = chimera.triggers.addHandler(
            CLOSE_SESSION, lambda t, a1, a2, s=self: s.Quit(), None)
        self._monitorChangesHandlerID = None
        # deregister other handlers on APPQUIT...
        chimera.triggers.addHandler(chimera.APPQUIT, self.destroy, None)
        if self.autoAssociate == None:
            if len(self.seqs) == 1:
                self.intrinsicStructure = True
            else:
                self.autoAssociate = False
                self.associate(None)
        else:
            self._newModelsCB(models=chimera.openModels.list())
        self._makeSequenceRegions()
        if self.prefs[LOAD_PDB_AUTO]:
            # delay calling _loadStructures to give any structures
            # opened along with MAV a chance to load
            parent.after_idle(lambda: self._loadStructures(auto=1))
        """
        self.tool_window.manage(
            'side' if self.seq_canvas.wrap_okay() else 'top')
Exemplo n.º 22
0
 def delete(self):
     from chimerax import atomic
     atomic.get_triggers(self._session()).remove_handler(self._handler)
     self._handler = None
     Graph.delete(self)
Exemplo n.º 23
0
 def delete(self):
     global_triggers = get_triggers()
     global_triggers.remove_handler(self._changes)
     super().delete()
Exemplo n.º 24
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        global_triggers = get_triggers()
        self._changes = global_triggers.add_handler("changes",
                                                    self.check_changes)
Exemplo n.º 25
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        self.display_name = "Models"
        self.settings = ModelPanelSettings(session, "ModelPanel")
        last = self.settings.last_use
        from time import time
        now = self.settings.last_use = time()
        short_titles = last != None and now - last < 777700 # about 3 months

        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self, close_destroys=False)
        parent = tw.ui_area
        from PyQt5.QtWidgets import QTreeWidget, QHBoxLayout, QVBoxLayout, QAbstractItemView, \
            QFrame, QPushButton, QSizePolicy
        class SizedTreeWidget(QTreeWidget):
            def sizeHint(self):
                from PyQt5.QtCore import QSize
                # side buttons will keep the vertical size reasonable
                if getattr(self, '_first_size_hint_call', True):
                    self._first_size_hint_call = False
                    width = 0
                else:
                    width = self.header().length()
                return QSize(width, 200)
        self.tree = SizedTreeWidget()
        self.tree.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.tree.keyPressEvent = session.ui.forward_keystroke
        self.tree.expanded.connect(self._ensure_id_width)
        layout = QHBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)
        layout.addWidget(self.tree)
        layout.setStretchFactor(self.tree, 1)
        parent.setLayout(layout)
        shown_title = "" if short_titles else "Shown"
        sel_title = "" if short_titles else "Select"
        self.tree.setHeaderLabels(["Name", "ID", " ", shown_title, sel_title])
        from chimerax.ui.icons import get_qt_icon
        self.tree.headerItem().setIcon(3, get_qt_icon("shown"))
        self.tree.headerItem().setToolTip(3, "Shown")
        self.tree.headerItem().setIcon(4, get_qt_icon("select"))
        self.tree.headerItem().setToolTip(4, "Selected")
        self.tree.setColumnWidth(self.NAME_COLUMN, 200)
        self.tree.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tree.setAnimated(True)
        self.tree.setUniformRowHeights(True)
        self.tree.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tree.itemChanged.connect(self._tree_change_cb)
        buttons_layout = QVBoxLayout()
        layout.addLayout(buttons_layout)
        self._items = []
        for model_func in [close, hide, show, view]:
            button = QPushButton(model_func.__name__.capitalize())
            buttons_layout.addWidget(button)
            button.clicked.connect(lambda chk, self=self, mf=model_func, ses=session:
                mf([self.models[row] for row in [self._items.index(i)
                    for i in self.tree.selectedItems()]] or self.models, ses))
        self.simply_changed_models = set()
        self.check_model_list = True
        self.countdown = 1
        self.self_initiated = False
        from chimerax.core.models import ADD_MODELS, REMOVE_MODELS, \
            MODEL_DISPLAY_CHANGED, MODEL_ID_CHANGED, MODEL_NAME_CHANGED
        from chimerax.core.selection import SELECTION_CHANGED
        session.triggers.add_handler(SELECTION_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, countdown=3))
        session.triggers.add_handler(MODEL_DISPLAY_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, simple_change=True, countdown=(0,3)))
        session.triggers.add_handler(ADD_MODELS,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True, countdown=(3,10)))
        session.triggers.add_handler(REMOVE_MODELS,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True))
        session.triggers.add_handler(MODEL_ID_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True, countdown=3))
        session.triggers.add_handler(MODEL_NAME_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, simple_change=True, countdown=3))
        from chimerax import atomic
        atomic.get_triggers().add_handler("changes", self._changes_cb)
        self._frame_drawn_handler = None
        tw.manage(placement="side")
        tw.shown_changed = self._shown_changed
Exemplo n.º 26
0
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