Пример #1
0
def register_command(logger):
    global _registered
    if _registered:
        # registration can be called for both main command and alias, so only do once...
        return
    _registered = True
    from chimerax.core.commands import CmdDesc, register, FloatArg, StringArg, \
        BoolArg, NoneArg, TopModelsArg, create_alias, Or, DynamicEnum
    from chimerax.atomic import AtomsArg
    from chimerax import sim_matrices
    desc = CmdDesc(
        required=[('match_atoms', AtomsArg)],
        required_arguments=['to'],
        keyword=[
            ('to', AtomsArg), ('pairing', StringArg), ('alg', StringArg),
            ('verbose', BoolArg), ('ss_fraction', Or(FloatArg, BoolArg)),
            ('matrix',
             DynamicEnum(
                 lambda logger=logger: sim_matrices.matrices(logger).keys())),
            ('gap_open', FloatArg), ('hgap', FloatArg), ('sgap', FloatArg),
            ('ogap', FloatArg), ('cutoff_distance', Or(FloatArg, NoneArg)),
            ('gap_extend', FloatArg), ('bring', TopModelsArg),
            ('show_alignment', BoolArg), ('compute_ss', BoolArg),
            ('mat_hh', FloatArg), ('mat_ss', FloatArg), ('mat_oo', FloatArg),
            ('mat_hs', FloatArg), ('mat_ho', FloatArg), ('mat_so', FloatArg),
            ('keep_computed_ss', BoolArg)
        ],
        synopsis='Align atomic structures using sequence alignment')
    register('matchmaker', desc, cmd_match, logger=logger)
    create_alias('mmaker',
                 "%s $*" % 'matchmaker',
                 logger=logger,
                 url="help:user/commands/matchmaker.html")
Пример #2
0
 def settings_info(self):
     name, defaults = super().settings_info()
     from chimerax.core.commands import EnumOf, FloatArg, IntArg, Bounded, PositiveIntArg, BoolArg
     from chimerax.sim_matrices import matrices
     matrix_names = list(matrices(self.alignment.session).keys())
     defaults.update({
         'style': (EnumOf(self.styles), self.STYLE_AL2CO),
         'al2co_freq': (Bounded(IntArg, min=0, max=2), 2),
         'al2co_cons': (Bounded(IntArg, min=0, max=2), 0),
         'al2co_window': (PositiveIntArg, 1),
         'al2co_gap': (Bounded(FloatArg, min=0, max=1), 0.5),
         'al2co_matrix': (EnumOf(matrix_names), "BLOSUM-62"),
         'al2co_transform': (Bounded(IntArg, min=0, max=2), 0),
         'initially_shown': (BoolArg, True),
     })
     return "conservation sequence header", defaults
Пример #3
0
    def add_options(self,
                    options_container,
                    *,
                    category=None,
                    verbose_labels=True):
        from PyQt5.QtWidgets import QVBoxLayout
        from PyQt5.QtCore import Qt
        option_data = self.option_data()
        self._add_options(options_container, category, verbose_labels,
                          option_data)
        if category is None:
            args = ()
        else:
            args = (category, )
        self.al2co_options_widget, al2co_options = options_container.add_option_group(
            *args,
            group_label="AL2CO parameters",
            group_alignment=Qt.AlignLeft)
        from chimerax.sim_matrices import matrices, matrix_name_key_func
        matrix_names = list(matrices(self.alignment.session).keys())
        matrix_names.append("identity")
        matrix_names.sort(key=matrix_name_key_func)

        class Al2coMatrixOption(EnumOption):
            values = matrix_names

        from chimerax.ui.options import IntOption, FloatOption
        al2co_option_data = [
            ("frequency estimation method", 'al2co_freq', Al2coFrequencyOption,
             {},
             "Method to estimate position-specific amino acid frequencies"),
            ("conservation measure", 'al2co_cons', Al2coConservationOption, {},
             "Conservation calculation strategy"),
            ("averaging window", 'al2co_window', IntOption, {
                'min': 1
            }, "Window size for conservation averaging"),
            ("gap fraction", 'al2co_gap', FloatOption, {
                'min': 0.0,
                'max': 1.0
            },
             "Conservations are computed for columns only if the fraction of gaps is less than this value"
             ),
        ]
        self._add_options(al2co_options, None, False, al2co_option_data)
        layout = QVBoxLayout()
        layout.addWidget(al2co_options, alignment=Qt.AlignLeft)
        from chimerax.ui.widgets import Citation
        layout.addWidget(Citation(self.alignment.session,
                                  '\n'.join(self.AL2CO_cite),
                                  prefix=self.AL2CO_cite_prefix,
                                  pubmed_id=11524371),
                         alignment=Qt.AlignLeft)
        self.al2co_options_widget.setLayout(layout)
        self.al2co_sop_options_widget, al2co_sop_options = al2co_options.add_option_group(
            group_label="Sum-of-pairs parameters")
        al2co_sop_option_data = [
            ("matrix", 'al2co_matrix', Al2coMatrixOption, {},
             "Similarity matrix used by sum-of-pairs measure"),
            ("matrix transformation", 'al2co_transform', Al2coTransformOption,
             {}, "Transform applied to similarity matrix as follows:\n"
             "\t%s: identity substitutions have same value\n"
             "\t%s: adjustment so that 2-sequence alignment yields\n"
             "\t\tsame score as in original matrix" %
             tuple(Al2coTransformOption.labels[1:]))
        ]
        self._add_options(al2co_sop_options, None, False,
                          al2co_sop_option_data)
        sop_layout = QVBoxLayout()
        sop_layout.addWidget(al2co_sop_options)
        self.al2co_sop_options_widget.setLayout(sop_layout)

        if self.settings.style == self.STYLE_AL2CO:
            if self.settings.al2co_cons != 2:
                self.al2co_sop_options_widget.hide()
        else:
            self.al2co_options_widget.hide()
Пример #4
0
def cmd_match(session,
              match_atoms,
              to=None,
              pairing=defaults["chain_pairing"],
              alg=defaults["alignment_algorithm"],
              verbose=defaults['verbose_logging'],
              bring=None,
              ss_fraction=defaults["ss_mixture"],
              matrix=defaults["matrix"],
              gap_open=defaults["gap_open"],
              hgap=defaults["helix_open"],
              sgap=defaults["strand_open"],
              ogap=defaults["other_open"],
              cutoff_distance=defaults["iter_cutoff"],
              gap_extend=defaults["gap_extend"],
              show_alignment=defaults['show_alignment'],
              compute_ss=defaults["compute_ss"],
              keep_computed_ss=defaults['overwrite_ss'],
              mat_hh=default_ss_matrix[('H', 'H')],
              mat_ss=default_ss_matrix[('S', 'S')],
              mat_oo=default_ss_matrix[('O', 'O')],
              mat_hs=default_ss_matrix[('H', 'S')],
              mat_ho=default_ss_matrix[('H', 'O')],
              mat_so=default_ss_matrix[('S', 'O')]):
    """wrapper for command-line command (friendlier args)"""

    # 'to' only needed to sidestep problem with adjacent atom specs...
    ref_atoms = to

    from chimerax import sim_matrices
    if matrix not in sim_matrices.matrices(session.logger):
        raise UserError("No such matrix name: %s" % str(matrix))
    if pairing == CP_SPECIFIC_SPECIFIC:
        matches = match_atoms.residues.chains.unique()
    elif pairing == CP_SPECIFIC_BEST:
        matches = match_atoms.structures.unique()
    if pairing == CP_SPECIFIC_SPECIFIC or pairing == CP_SPECIFIC_BEST:
        refs = ref_atoms.residues.chains.unique()
        if not refs:
            raise UserError("No 'to' chains specified")
        if pairing == CP_SPECIFIC_BEST:
            if len(refs) > 1:
                raise UserError("Specify a single 'to' chain only")
    else:
        ref_mols = ref_atoms.structures.unique()
        if not ref_mols:
            raise UserError("No 'to' model specified")
        if len(ref_mols) > 1:
            raise UserError("Specify a single 'to' model only")
        refs = ref_mols
        matches = match_atoms.structures.unique()
    if not matches:
        raise UserError("No molecules/chains to match specified")
    # the .subtract() method of Collections does not preserve order (as of 10/28/16),
    # so "subtract" by hand...
    refs = [r for r in refs if r not in matches]
    if not matches:
        raise UserError("Must use different reference and match structures")
    if bring is not None:
        bring = set(bring)
        match_structures = matches if pairing != CP_SPECIFIC_SPECIFIC \
            else matches.structures.unique()
        if len(match_structures) > 1:
            raise UserError(
                "'bring' option can only be used when exactly one structure is being"
                " matched")
        ref_structures = refs if pairing == CP_BEST_BEST else set(
            [r.structure for r in refs])
        for test_structures, text in [(match_structures, "match"),
                                      (ref_structures, "reference")]:
            for s in test_structures:
                if s in bring:
                    bring.discard(s)
                else:
                    for b in bring:
                        if b.id == s.id[:len(b.id)]:
                            raise UserError(
                                "Cannot 'bring' parent model of %s structure" %
                                text)
        if len(bring) == 0:
            session.logger.warning(
                "'bring' arg specifies no non-match/ref structures")
            bring = None
    if pairing == CP_SPECIFIC_SPECIFIC:
        if len(refs) != len(matches):
            raise UserError("Different number of reference/match"
                            " chains (%d ref, %d match)" %
                            (len(refs), len(matches)))
        match_items = zip(refs, matches)
    else:
        match_items = (refs[0], matches)
    ss_matrix = {}
    ss_matrix[('H', 'H')] = float(mat_hh)
    ss_matrix[('S', 'S')] = float(mat_ss)
    ss_matrix[('O', 'O')] = float(mat_oo)
    ss_matrix[('H', 'S')] = ss_matrix[('S', 'H')] = float(mat_hs)
    ss_matrix[('H', 'O')] = ss_matrix[('O', 'H')] = float(mat_ho)
    ss_matrix[('S', 'O')] = ss_matrix[('O', 'S')] = float(mat_so)
    ret_vals = match(session,
                     pairing,
                     match_items,
                     matrix,
                     alg,
                     gap_open,
                     gap_extend,
                     ss_fraction=ss_fraction,
                     ss_matrix=ss_matrix,
                     cutoff_distance=cutoff_distance,
                     show_alignment=show_alignment,
                     bring=bring,
                     domain_residues=(ref_atoms.residues.unique(),
                                      match_atoms.residues.unique()),
                     gap_open_helix=hgap,
                     gap_open_strand=sgap,
                     gap_open_other=ogap,
                     compute_ss=compute_ss,
                     keep_computed_ss=keep_computed_ss,
                     verbose=verbose)
    return ret_vals
Пример #5
0
    def run_matchmaker(self):
        from chimerax.core.commands import StringArg, BoolArg, FloatArg, DynamicEnum, NoneArg
        from .settings import defaults, get_settings
        settings = get_settings(self.session)
        chain_pairing = self.chain_pairing_option.value
        ref_widget, match_widget = self.matching_widgets[chain_pairing]
        ref_value = ref_widget.value
        match_value = match_widget.value
        if chain_pairing == CP_SPECIFIC_SPECIFIC:
            ref_spec = "".join([rchain.atomspec for rchain, mchain in match_value])
        else:
            ref_spec = ref_value.atomspec
        if not ref_spec:
            raise UserError("No reference and/or match structure/chain chosen")
        if self.ref_sel_restrict.isChecked():
            ref_spec = ref_spec + " & sel"
        if chain_pairing == CP_SPECIFIC_SPECIFIC:
            match_spec = "".join([mchain.atomspec for rchain, mchain in match_value])
        else:
            from chimerax.core.commands import concise_model_spec
            match_spec = concise_model_spec(self.session, match_value)
        if not match_spec:
            raise UserError("No match structure/chain(s) chosen")
        if self.match_sel_restrict.isChecked():
            match_spec = match_spec + " & sel"

        cmd = "matchmaker " + match_spec + " to " + ref_spec
        if chain_pairing != defaults['chain_pairing']:
            cmd += ' pairing ' + chain_pairing

        alg = settings.alignment_algorithm
        if alg != defaults['alignment_algorithm']:
            cmd += ' alg ' + StringArg.unparse(alg)

        verbose = settings.verbose_logging
        if verbose != defaults['verbose_logging']:
            cmd += ' verbose ' + BoolArg.unparse(verbose)

        use_ss = settings.use_ss
        if use_ss:
            ss_fraction = settings.ss_mixture
            if ss_fraction != defaults['ss_mixture']:
                cmd += ' ssFraction ' + FloatArg.unparse(ss_fraction)
        else:
            cmd += ' ssFraction ' + BoolArg.unparse(use_ss)

        matrix = settings.matrix
        if matrix != defaults['matrix']:
            from chimerax import sim_matrices
            cmd += ' matrix ' + DynamicEnum(
                lambda ses=self.session: sim_matrices.matrices(ses.logger).keys()).unparse(matrix)

        gap_open = settings.gap_open
        if not use_ss and gap_open != defaults['gap_open']:
            cmd += ' gapOpen ' + FloatArg.unparse(gap_open)

        helix_open = settings.helix_open
        from chimerax.core.commands import run
        if helix_open != defaults['helix_open']:
            cmd += ' hgap ' + FloatArg.unparse(helix_open)

        strand_open = settings.strand_open
        from chimerax.core.commands import run
        if strand_open != defaults['strand_open']:
            cmd += ' sgap ' + FloatArg.unparse(strand_open)

        other_open = settings.other_open
        from chimerax.core.commands import run
        if other_open != defaults['other_open']:
            cmd += ' ogap ' + FloatArg.unparse(other_open)

        iterate = settings.iterate
        if iterate:
            iter_cutoff = settings.iter_cutoff
            if iter_cutoff != defaults['iter_cutoff']:
                cmd += ' cutoffDistance ' + FloatArg.unparse(iter_cutoff)
        else:
            cmd += ' cutoffDistance ' + NoneArg.unparse(None)

        gap_extend = settings.gap_extend
        if gap_extend != defaults['gap_extend']:
            cmd += ' gapExtend ' + FloatArg.unparse(gap_extend)

        if self.bring_model_list.isEnabled():
            models = self.bring_model_list.value
            if models:
                cmd += ' bring ' + concise_model_spec(self.session, models)

        show_alignment = settings.show_alignment
        if show_alignment != defaults['show_alignment']:
            cmd += ' showAlignment ' + BoolArg.unparse(show_alignment)

        compute_ss = settings.compute_ss
        if compute_ss != defaults['compute_ss']:
            cmd += ' computeSs ' + BoolArg.unparse(compute_ss)

        overwrite_ss = settings.overwrite_ss
        if compute_ss and overwrite_ss != defaults['overwrite_ss']:
            cmd += ' keepComputedSs ' + BoolArg.unparse(overwrite_ss)

        ss_matrix = settings.ss_scores
        if ss_matrix != defaults['ss_scores']:
            for key, val in ss_matrix.items():
                order = ['H', 'S', 'O']
                if val != defaults['ss_scores'][key]:
                    let1, let2 = key
                    if order.index(let1) > order.index(let2):
                        continue
                    cmd += ' mat' + let1 + let2.lower() + ' ' + FloatArg.unparse(val)

        run(self.session, cmd)