示例#1
0
    def restore_selected(self):
        items = [item for item in self.tree.selectedItems()]
        model_dict = self.session.filereader_manager.filereader_dict
        models = list(model_dict.keys())
        for item in items:
            parent = item.parent()
            mdl = models[self.tree.indexOfTopLevelItem(parent)]
            if parent is None:
                fr = model_dict[mdl][-1]
            else:
                fr = model_dict[mdl][parent.indexOfChild(item)]

            fr_rescol = ResidueCollection(fr)
            fr_rescol.update_chix(mdl)
            if fr.all_geom is not None and len(fr.all_geom) > 1:
                coordsets = fr_rescol.all_geom_coordsets(fr)

                mdl.remove_coordsets()
                mdl.add_coordsets(coordsets)

                for i, coordset in enumerate(coordsets):
                    mdl.active_coordset_id = i + 1
                    
                    for atom, coord in zip(mdl.atoms, coordset):
                        atom.coord = coord
                
                mdl.active_coordset_id = 1
示例#2
0
def fuseRing(session,
             selection=None,
             rings=None,
             newName=None,
             modify=True,
             minimize=False,
             available=False):
    if available:
        fuseRing_list(session)
        return

    if not selection:
        selection = selected_atoms(session)

    if not rings:
        session.logger.error("missing required \"rings\" argument")
        return

    if newName is None:
        pass
    elif any(len(name.strip()) > 4 for name in newName):
        raise RuntimeError("residue names must be 4 characters or less")
    elif not all(name.isalnum() for name in newName):
        raise RuntimeError("invalid residue name: %s" % newName)
    elif len(rings) != len(newName):
        raise RuntimeError(
            "number of substituents is not the same as the number of new names"
        )

    if len(selection) < 2:
        raise RuntimeWarning("two atoms must be selected per molecule")

    models = {}
    for atom in selection:
        if atom.structure not in models:
            models[atom.structure] = [atom]
        else:
            models[atom.structure].append(atom)

        if len(models[atom.structure]) > 2:
            raise RuntimeError("only two atoms can be selected on any model")

    first_pass = True
    new_structures = []
    for i, ringname in enumerate(rings):
        ringname = ringname.strip()

        for model in models:
            atom1 = models[model][0]
            atom2 = models[model][1]
            if modify and first_pass:
                convert = minimal_ring_convert(model, *models[model])
                if newName is not None:
                    for res in convert:
                        res.name = newName[i]

                rescol = ResidueCollection(model, convert_residues=convert)

                target = rescol.find(
                    [AtomSpec(atom1.atomspec),
                     AtomSpec(atom2.atomspec)])

            elif modify and not first_pass:
                raise RuntimeError("only the first model can be replaced")
            else:
                model_copy = model.copy()
                a1 = model_copy.atoms[model.atoms.index(models[model][0])]
                a2 = model_copy.atoms[model.atoms.index(models[model][1])]
                convert = minimal_ring_convert(model_copy, a1, a2)
                if newName is not None:
                    for res in convert:
                        res.name = newName[i]

                rescol = ResidueCollection(model_copy,
                                           convert_residues=convert)

                target = rescol.find(
                    [AtomSpec(a1.atomspec),
                     AtomSpec(a2.atomspec)])

            rescol.ring_substitute(target, ringname, minimize=minimize)

            if modify:
                rescol.update_chix(model)
            else:
                rescol.update_chix(model_copy)
                new_structures.append(model_copy)

        first_pass = False

    if not modify:
        session.models.add(new_structures)
示例#3
0
    def mouse_up(self, event):
        if event.shift_down():
            _ElementPicker(self.session, "pick element")
            return

        if not self.element:
            self.session.logger.warning(
                "no element selected; shift-click to set element")
            self.session.logger.status(
                "no element selected; shift-click to set element")
            _ElementPicker(self.session, "pick element")
            return

        x, y = event.position()
        pick = self.view.picked_object(x, y)

        if not pick:
            x1, x2 = self.session.main_view.clip_plane_points(x, y)
            coords = (x1 + x2) / 2
            new_fragment = _ModelSelector(self.session, "place atom in model",
                                          coords)
            if new_fragment.model_selector.count() == 1:
                new_fragment.new_atom()
            return

        # import cProfile
        #
        # profile = cProfile.Profile()
        # profile.enable()

        vsepr = self.vsepr

        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
            goal = 1
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
            goal = 2
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
            goal = 2
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
            goal = 2
        elif vsepr == "trigonal planar":
            goal = 3
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"
            goal = 3
        elif vsepr == "tetrahedral":
            goal = 4
        else:
            goal = len(Atom.get_shape(vsepr)) - 1

        if not isinstance(pick, PickedAtom):
            return

        atom = pick.atom
        # # use built-in ChimeraX command for some of the more common things
        # # because it's faster for proteins
        # if False:
        #     run(
        #         self.session,
        #         "build modify %s %s %i geometry %s" % (
        #             atom.atomspec,
        #             self.element,
        #             goal,
        #             vsepr,
        #         )
        #     )
        #

        frags = []
        for neighbor in atom.neighbors:
            frags.append(
                get_fragment(neighbor,
                             stop=atom,
                             max_len=atom.structure.num_atoms))

        residues = [atom.residue]
        hold_steady = None
        for i, frag in enumerate(sorted(frags, key=len)):
            if i == len(frags) - 1:
                hold_steady = AtomSpec(frag[0].atomspec)
                residues.append(frag[0].residue)
                continue
            residues.extend(frag.residues)

        rescol = ResidueCollection(atom.structure,
                                   convert_residues=set(residues),
                                   refresh_ranks=False)
        res = [
            residue for residue in rescol.residues
            if residue.chix_residue is atom.residue
        ][0]
        target = res.find_exact(AtomSpec(atom.atomspec))[0]
        adjust_hydrogens = vsepr
        if vsepr is not False:
            cur_bonds = len(target.connected)
            change_Hs = goal - cur_bonds
            adjust_hydrogens = (change_Hs, vsepr)

        rescol.change_element(
            target,
            self.element,
            adjust_bonds=True,
            adjust_hydrogens=adjust_hydrogens,
            hold_steady=hold_steady,
        )

        res.update_chix(res.chix_residue,
                        apply_preset=True,
                        refresh_connected=True)
        rescol.update_chix(atom.structure,
                           apply_preset=False,
                           refresh_connected=False)
示例#4
0
    def job_finished(self, trigger_name, job):
        """when a job is finished, open or update the structure as requested"""
        if self.session.seqcrow_settings.settings.JOB_FINISHED_NOTIFICATION == \
          'log and popup notifications' and self.session.ui.is_gui:
            #it's just an error message for now
            #TODO: make my own logger
            self.session.logger.error("%s: %s" % (trigger_name, job))

        else:
            job.session.logger.info("%s: %s" % (trigger_name, job))

        if isinstance(job, LocalJob):
            self._thread = None
            if not hasattr(job, "output_name") or \
               not os.path.exists(job.output_name):
                job.error = True

            else:
                fr = FileReader(job.output_name, just_geom=False)
                #XXX: finished is not added to the FileReader for ORCA and Psi4 when finished = False
                if 'finished' not in fr.other or not fr.other['finished']:
                    job.error = True

        if job.auto_update and (
                job.theory.geometry.chix_atomicstructure is not None
                and not job.theory.geometry.chix_atomicstructure.deleted):
            if os.path.exists(job.output_name):
                finfo = job.output_name
                try:
                    finfo = (job.output_name, job.format_name, None)

                    fr = FileReader(finfo, get_all=True, just_geom=False)
                    if len(fr.atoms) > 0:
                        job.session.filereader_manager.triggers.activate_trigger(
                            ADD_FILEREADER,
                            ([job.theory.geometry.chix_atomicstructure], [fr]))

                        rescol = ResidueCollection(fr)
                        rescol.update_chix(
                            job.theory.geometry.chix_atomicstructure)

                except:
                    job.update_structure()

            if fr.all_geom is not None and len(fr.all_geom) > 1:
                coordsets = rescol.all_geom_coordsets(fr)

                job.theory.geometry.chix_atomicstructure.remove_coordsets()
                job.theory.geometry.chix_atomicstructure.add_coordsets(
                    coordsets)

                for i, coordset in enumerate(coordsets):
                    job.theory.geometry.chix_atomicstructure.active_coordset_id = i + 1

                    for atom, coord in zip(
                            job.theory.geometry.chix_atomicstructure.atoms,
                            coordset):
                        atom.coord = coord

                job.theory.geometry.chix_atomicstructure.active_coordset_id = job.theory.geometry.chix_atomicstructure.num_coordsets

        elif job.auto_open or job.auto_update:
            if hasattr(job, "output_name") and os.path.exists(job.output_name):
                if job.format_name:
                    run(
                        job.session, "open \"%s\" coordsets true format %s" %
                        (job.output_name, job.format_name))
                else:
                    run(job.session,
                        "open \"%s\" coordsets true" % job.output_name)
            else:
                self.session.logger.error("could not open output of %s" %
                                          repr(job))

        self.triggers.activate_trigger(JOB_QUEUED, trigger_name)
        pass
示例#5
0
def substitute(
    session,
    selection=None,
    substituents=None,
    newName=None,
    guessAttachment=True,
    modify=True,
    minimize=False,
    useRemoteness=False,
    available=False,
    newResidue=False,
):

    if available:
        substitute_list(session)
        return

    if not selection:
        selection = selected_atoms(session)

    if not substituents:
        session.logger.error("missing required \"substituents\" argument")
        return

    attached = {}

    if newName is None:
        newName = [None for s in substituents]
    elif any(len(name.strip()) > 4 for name in newName):
        raise RuntimeError("residue names must be 4 characters or less")
    elif not all(name.isalnum() for name in newName):
        raise RuntimeError("invalid residue name: %s" % " ".join(newName))
    elif len(substituents) != len(newName):
        raise RuntimeError(
            "number of substituents is not the same as the number of new names"
        )

    if not guessAttachment:
        models, attached = avoidTargets(selection)
    else:
        models, attached = guessAttachmentTargets(selection, session)

    first_pass = True
    new_structures = []
    for ndx, subname in enumerate(substituents):
        subname = subname.strip()
        sub = Substituent(subname)

        # when minimizing, we only want to deal with residues that are close to the substituent
        # determine the size of the new substituent to limit this
        if minimize:
            size = 5
            for atom in sub.atoms:
                d = np.linalg.norm(atom.coords)
                if d > size:
                    size = d

        for model in models:
            if modify and first_pass:
                conv_res = []
                for res in models[model]:
                    if res not in conv_res:
                        conv_res.append(res)

                    if minimize:
                        for chix_res in model.residues:
                            if chix_res in conv_res:
                                continue

                            added_res = False
                            for atom in chix_res.atoms:
                                for target in models[model][res]:
                                    d = np.linalg.norm(atom.coord -
                                                       target.coord)
                                    if d < (size + 3):
                                        conv_res.append(chix_res)
                                        added_res = True
                                        break

                                if added_res:
                                    break

                rescol = ResidueCollection(model, convert_residues=conv_res)
                for res in models[model]:
                    for target in models[model][res]:
                        if attached is not None:
                            end = AtomSpec(attached[target].atomspec)
                        else:
                            end = None

                        # call substitute on the ResidueCollection b/c we need to see
                        # the other residues if minimize=True
                        rescol.substitute(
                            sub.copy(),
                            AtomSpec(target.atomspec),
                            attached_to=end,
                            minimize=minimize,
                            use_greek=useRemoteness,
                            new_residue=newResidue,
                            new_name=newName[ndx],
                        )

                rescol.update_chix(model)

            elif modify and not first_pass:
                raise RuntimeError("only the first model can be replaced")
            else:
                model_copy = model.copy()

                conv_res = [
                    model_copy.residues[i] for i in
                    [model.residues.index(res) for res in models[model]]
                ]
                # modifying_residues = [model_copy.residues[i] for i in [model.residues.index(res) for res in models[model]]]
                modifying_residues = [r for r in conv_res]

                if minimize:
                    for chix_res in model_copy.residues:
                        if chix_res in conv_res:
                            continue

                        added_res = False
                        for res in models[model]:
                            for target in models[model][res]:
                                for atom in chix_res.atoms:
                                    d = np.linalg.norm(atom.coord -
                                                       target.coord)
                                    if d < (size + 3):
                                        conv_res.append(chix_res)
                                        added_res = True
                                        break

                                if added_res:
                                    break

                            if added_res:
                                break

                rescol = ResidueCollection(model_copy,
                                           convert_residues=conv_res)
                for residue, res in zip(modifying_residues, models[model]):
                    for target in models[model][res]:
                        if attached is not None:
                            end = AtomSpec(model_copy.atoms[model.atoms.index(
                                attached[target])].atomspec)
                        else:
                            end = None

                        rescol.substitute(
                            sub.copy(),
                            AtomSpec(model_copy.atoms[model.atoms.index(
                                target)].atomspec),
                            attached_to=end,
                            minimize=minimize,
                            use_greek=useRemoteness,
                            new_residue=newResidue,
                            new_name=newName[ndx],
                        )

                rescol.update_chix(model_copy)

                new_structures.append(model_copy)

        first_pass = False

    if not modify:
        session.models.add(new_structures)
示例#6
0
    def do_maplig(self):
        lignames = self.ligname.text()
        selection = selected_atoms(self.session)
        
        if len(selection) < 1:
            raise RuntimeWarning("nothing selected")
        
        models = {}
        for atom in selection:
            if atom.structure not in models:
                models[atom.structure] = [AtomSpec(atom.atomspec)]
            else:
                models[atom.structure].append(AtomSpec(atom.atomspec))        
        
        first_pass = True
        new_structures = []
        for ligname in lignames.split(','):
            ligname = ligname.strip()
            lig = Component(ligname)
            for model in models:
                if self.close_previous_bool and first_pass:
                    rescol = ResidueCollection(model)
                elif self.close_previous_bool and not first_pass:
                    raise RuntimeError("only the first model can be replaced")
                else:
                    model_copy = model.copy()
                    rescol = ResidueCollection(model_copy)
                    for i, atom in enumerate(model.atoms):
                        rescol.atoms[i].atomspec = atom.atomspec
                        rescol.atoms[i].add_tag(atom.atomspec)
                        rescol.atoms[i].chix_atom = atom

                target = rescol.find(models[model])
                if len(target) % len(lig.key_atoms) == 0:
                    k = 0
                    ligands = []
                    while k != len(target):
                        res_lig = ResidueCollection(lig.copy(), comment=lig.comment)
                        res_lig.parse_comment()
                        res_lig = Component(res_lig, key_atoms = ",".join([str(k + 1) for k in res_lig.other["key_atoms"]]))
                        ligands.append(res_lig)
                        k += len(lig.key_atoms)
                else:
                    raise RuntimeError("number of key atoms no not match: %i now, new ligand has %i" % (len(target), len(lig.key_atoms)))
                
                rescol.map_ligand(ligands, target)

                for center_atom in rescol.center:
                    center_atom.connected = set([])
                    for atom in rescol.atoms:
                        if atom not in rescol.center:
                            if center_atom.is_connected(atom):
                                atom.connected.add(center_atom)
                                center_atom.connected.add(atom)
                
                if self.close_previous_bool:    
                    rescol.update_chix(model)
                else:
                    struc = rescol.get_chimera(self.session)
                    new_structures.append(struc)
            
            first_pass = False
        
        if not self.close_previous_bool:
            self.session.models.add(new_structures)