def new_atom(self): element = ChangeElementMouseMode.element adjust_bonds = True vsepr = ChangeElementMouseMode.vsepr if vsepr == "do not change": vsepr = False elif vsepr == "linear (1 bond)": vsepr = "linear 1" elif vsepr == "linear (2 bonds)": vsepr = "linear 2" elif vsepr == "trigonal planar (2 bonds)": vsepr = "bent 2 planar" elif vsepr == "tetrahedral (2 bonds)": vsepr = "bent 2 tetrahedral" elif vsepr == "tetrahedral (3 bonds)": vsepr = "bent 3 tetrahedral" if vsepr: atoms = Atom.get_shape(vsepr) atoms[0].element = element for atom in atoms[1:]: atom.element = "H" if adjust_bonds: # this works b/c all atoms are 1 angstrom from the center # just multiply by the distance we want expected_dist = RADII[element] + RADII["H"] for atom in atoms[1:]: atom.coords *= expected_dist for atom in atoms[1:]: atoms[0].connected.add(atom) atom.connected.add(atoms[0]) else: atoms = [Atom(element=element, coords=np.zeros(3))] rescol = ResidueCollection(atoms, name="new", refresh_connected=False) rescol.coord_shift(self._coords) model = self.model_selector.currentData() if model is None: chix = rescol.get_chimera(self.session) self.session.models.add([chix]) apply_seqcrow_preset(chix, fallback="Ball-Stick-Endcap") else: res = model.new_residue("new", "a", len(model.residues) + 1) rescol.residues[0].update_chix(res) run( self.session, "select add %s" % " ".join([atom.atomspec for atom in res.atoms])) self.delete()
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)
if isinstance(args.change_hs, int): adjust_hs = args.change_hs elif args.change_hs is None: adjust_hs = True else: adjust_hs = 0 new_vsepr = None if args.geometry: new_vsepr = args.geometry.replace("_", " ") if adjust_hs == 0 and new_vsepr is None: adjust_structure = False elif adjust_hs == 0 and new_vsepr: goal = len(Atom.get_shape(new_vsepr)) - 1 def goal_func(atom, goal=goal): return goal - len(atom.connected) adjust_structure = (goal_func, new_vsepr) elif adjust_hs is True: adjust_structure = True else: adjust_structure = (adjust_hs, new_vsepr) for f in glob_files(args.infile, parser=element_parser): if isinstance(f, str): if args.input_format is not None: infile = FileReader((f, args.input_format, None)) else: infile = FileReader(f) else:
def do_change_element(self): element = self.element.text() adjust_bonds = self.change_bonds.isChecked() self.settings.change_bonds = adjust_bonds vsepr = self.vsepr.currentText() 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 else: goal = len(Atom.get_shape(vsepr)) - 1 sel = selected_atoms(self.session) models, _ = guessAttachmentTargets(sel, self.session, allow_adjacent=False) for model in models: conv_res = list(models[model].keys()) for res in models[model]: for target in models[model][res]: for neighbor in target.neighbors: if neighbor.residue not in conv_res: conv_res.append(neighbor.residue) for pbg in self.session.models.list(type=PseudobondGroup): for pbond in pbg.pseudobonds: if target in pbond.atoms and all(atom.structure is model for atom in pbond.atoms): other_atom = pbond.other_atom(target) if other_atom.residue not in conv_res: conv_res.append(other_atom.residue) rescol = ResidueCollection(model, convert_residues=conv_res) for res in models[model]: residue = [resi for resi in rescol.residues if resi.chix_residue is res][0] for target in models[model][res]: targ = rescol.find_exact(AtomSpec(target.atomspec))[0] adjust_hydrogens = vsepr if vsepr is not False: cur_bonds = len(targ.connected) change_Hs = goal - cur_bonds adjust_hydrogens = (change_Hs, vsepr) residue.change_element(targ, element, adjust_bonds=adjust_bonds, adjust_hydrogens=adjust_hydrogens, ) residue.update_chix(res)