def bkchem_mol_to_oasa_mol(mol): m = oasa.molecule() for a in mol.atoms: m.add_vertex(bkchem_atom_to_oasa_atom(a)) for b in mol.bonds: b2 = bkchem_bond_to_oasa_bond(b) aa1, aa2 = b.atoms v1 = m.vertices[mol.atoms.index(aa1)] v2 = m.vertices[mol.atoms.index(aa2)] b2.vertices = (v1, v2) m.add_edge(v1, v2, b2) return m
def bkchem_mol_to_oasa_mol( mol): m = oasa.molecule() for a in mol.atoms: m.add_vertex( bkchem_atom_to_oasa_atom( a)) for b in mol.bonds: b2 = bkchem_bond_to_oasa_bond( b) aa1, aa2 = b.atoms v1 = m.vertices[ mol.atoms.index( aa1)] v2 = m.vertices[ mol.atoms.index( aa2)] b2.vertices = (v1, v2) m.add_edge( v1, v2, b2) return m
def _read_summary_formula(self, text): mols = [] for line in text.splitlines(): sum_dict = oasa.periodic_table.formula_dict(line) mol = oasa.molecule() for (symbol,count) in sum_dict.iteritems(): for i in range(count): a = oasa.atom(symbol) a.valency = 0 mol.add_vertex(a) mols.append(mol) return mols
def draw(self, show=True, filename=None, update=False, usecoords=False): """Create a 2D depiction of the molecule. Optional parameters: show -- display on screen (default is True) filename -- write to file (default is None) update -- update the coordinates of the atoms to those determined by the structure diagram generator (default is False) usecoords -- don't calculate 2D coordinates, just use the current coordinates (default is False) OASA is used for 2D coordinate generation and depiction. Tkinter and Python Imaging Library are required for image display. """ etab = ob.OBElementTable() if not oasa: errormessage = ("OASA not found, but is required for 2D structure " "generation and depiction. OASA is part of BKChem. " "See installation instructions for more " "information.") raise ImportError(errormessage) mol = oasa.molecule() for atom in self.atoms: v = mol.create_vertex() v.symbol = etab.GetSymbol(atom.atomicnum) v.charge = atom.formalcharge if usecoords: v.x, v.y, v.z = atom.coords[0] * 30., atom.coords[1] * 30., 0.0 mol.add_vertex(v) for bond in ob.OBMolBondIter(self.OBMol): e = mol.create_edge() e.order = bond.GetBO() if bond.IsHash(): e.type = "h" elif bond.IsWedge(): e.type = "w" mol.add_edge(bond.GetBeginAtomIdx() - 1, bond.GetEndAtomIdx() - 1, e) # I'm sure there's a more elegant way to do the following, but here goes... # let's set the stereochemistry around double bonds self.write("can") # Perceive UP/DOWNness for bond in ob.OBMolBondIter(self.OBMol): ends = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx() if bond.GetBO() == 2: stereobonds = [[b for b in ob.OBAtomBondIter(self.OBMol.GetAtom(x)) if b.GetIdx() != bond.GetIdx() and (b.IsUp() or b.IsDown())] for x in ends] if stereobonds[0] and stereobonds[1]: # Needs to be defined at either end if stereobonds[0][0].IsUp() == stereobonds[1][0].IsUp(): # Either both up or both down stereo = oasa.stereochemistry.cis_trans_stereochemistry.SAME_SIDE else: stereo = oasa.stereochemistry.cis_trans_stereochemistry.OPPOSITE_SIDE atomids = [(b[0].GetBeginAtomIdx(), b[0].GetEndAtomIdx()) for b in stereobonds] extremes = [] for id, end in zip(ends, atomids): if end[0] == id: extremes.append(end[1]) else: extremes.append(end[0]) center = mol.get_edge_between(mol.atoms[ends[0] - 1], mol.atoms[ends[1] - 1]) st = oasa.stereochemistry.cis_trans_stereochemistry( center = center, value = stereo, references = (mol.atoms[extremes[0] - 1], mol.atoms[ends[0] - 1], mol.atoms[ends[1] - 1], mol.atoms[extremes[1] - 1])) mol.add_stereochemistry(st) mol.remove_unimportant_hydrogens() if not usecoords: oasa.coords_generator.calculate_coords(mol, bond_length=30) if update: newcoords = [(v.x / 30., v.y / 30., 0.0) for v in mol.vertices] for atom, newcoord in zip(ob.OBMolAtomIter(self.OBMol), newcoords): atom.SetVector(*newcoord) if filename or show: maxx = max([v.x for v in mol.vertices]) minx = min([v.x for v in mol.vertices]) maxy = max([v.y for v in mol.vertices]) miny = min([v.y for v in mol.vertices]) maxcoord = max(maxx - minx, maxy - miny) fontsize = 16 bondwidth = 6 linewidth = 2 if maxcoord > 270: # 300 - margin * 2 for v in mol.vertices: v.x *= 270. / maxcoord v.y *= 270. / maxcoord fontsize *= math.sqrt(270. / maxcoord) bondwidth *= math.sqrt(270. / maxcoord) linewidth *= math.sqrt(270. / maxcoord) if filename: filedes = None else: filedes, filename = tempfile.mkstemp() canvas = oasa.cairo_out.cairo_out() canvas.show_hydrogens_on_hetero = True canvas.font_size = fontsize canvas.bond_width = bondwidth canvas.line_width = linewidth canvas.mol_to_cairo(mol, filename) if show: if not tk: errormessage = ("Tkinter or Python Imaging " "Library not found, but is required for image " "display. See installation instructions for " "more information.") raise ImportError(errormessage) root = tk.Tk() root.title((hasattr(self, "title") and self.title) or self.__str__().rstrip()) frame = tk.Frame(root, colormap="new", visual='truecolor').pack() image = PIL.open(filename) imagedata = piltk.PhotoImage(image) label = tk.Label(frame, image=imagedata).pack() quitbutton = tk.Button(root, text="Close", command=root.destroy).pack(fill=tk.X) root.mainloop() if filedes: os.close(filedes) os.remove(filename)
def draw(self, show=True, filename=None, update=False, usecoords=False): """Create a 2D depiction of the molecule. Optional parameters: show -- display on screen (default is True) filename -- write to file (default is None) update -- update the coordinates of the atoms to those determined by the structure diagram generator (default is False) usecoords -- don't calculate 2D coordinates, just use the current coordinates (default is False) OASA is used for depiction. Tkinter and Python Imaging Library are required for image display. """ writetofile = filename is not None if not usecoords: # Do the SDG sdg = cdk.layout.StructureDiagramGenerator() sdg.setMolecule(self.Molecule) sdg.generateExperimentalCoordinates() newmol = Molecule(sdg.getMolecule()) if update: for atom, newatom in zip(self.atoms, newmol.atoms): coords = newatom.Atom.getPoint2d() atom.Atom.setPoint3d(javax.vecmath.Point3d(coords.x, coords.y, 0.0)) else: newmol = self if writetofile or show: if writetofile: filedes = None else: filedes, filename = tempfile.mkstemp() # Create OASA molecule if not oasa: errormessage = ( "OASA not found, but is required for 2D structure " "depiction. OASA is part of BKChem. " "See installation instructions for more " "information." ) raise ImportError, errormessage mol = oasa.molecule() atomnos = [] for newatom in newmol.atoms: if not usecoords: coords = newatom.Atom.getPoint2d() else: coords = newatom.Atom.getPoint3d() if not coords: coords = newatom.Atom.getPoint2d() v = mol.create_vertex() v.charge = newatom.formalcharge v.symbol = _isofact.getElement(newatom.atomicnum).getSymbol() mol.add_vertex(v) v.x, v.y, v.z = coords.x * 30.0, coords.y * 30.0, 0.0 for i in range(self.Molecule.getBondCount()): bond = self.Molecule.getBond(i) bo = _revbondtypes[bond.getOrder()] atoms = [self.Molecule.getAtomNumber(x) for x in bond.atoms().iterator()] e = mol.create_edge() e.order = bo if bond.getStereo() == cdk.CDKConstants.STEREO_BOND_DOWN: e.type = "h" elif bond.getStereo() == cdk.CDKConstants.STEREO_BOND_UP: e.type = "w" mol.add_edge(atoms[0], atoms[1], e) mol.remove_unimportant_hydrogens() maxx = max([v.x for v in mol.vertices]) minx = min([v.x for v in mol.vertices]) maxy = max([v.y for v in mol.vertices]) miny = min([v.y for v in mol.vertices]) maxcoord = max(maxx - minx, maxy - miny) for v in mol.vertices: if str(v.x) == "-1.#IND": v.x = minx if str(v.y) == "-1.#IND": v.y = miny fontsize = 16 bondwidth = 6 linewidth = 2 if maxcoord > 270: # 300 - margin * 2 for v in mol.vertices: v.x *= 270.0 / maxcoord v.y *= 270.0 / maxcoord fontsize *= math.sqrt(270.0 / maxcoord) bondwidth *= math.sqrt(270.0 / maxcoord) linewidth *= math.sqrt(270.0 / maxcoord) canvas = oasa.cairo_out.cairo_out() canvas.show_hydrogens_on_hetero = True canvas.font_size = fontsize canvas.bond_width = bondwidth canvas.line_width = linewidth canvas.mol_to_cairo(mol, filename) if show: if not tk: errormessage = ( "Tkinter or Python Imaging " "Library not found, but is required for image " "display. See installation instructions for " "more information." ) raise ImportError, errormessage root = tk.Tk() root.title((hasattr(self, "title") and self.title) or self.__str__().rstrip()) frame = tk.Frame(root, colormap="new", visual="truecolor").pack() image = PIL.open(filename) imagedata = piltk.PhotoImage(image) label = tk.Label(frame, image=imagedata).pack() quitbutton = tk.Button(root, text="Close", command=root.destroy).pack(fill=tk.X) root.mainloop() if filedes: os.close(filedes) os.remove(filename)
def draw(self, show=True, filename=None, update=False, usecoords=False): """Create a 2D depiction of the molecule. Optional parameters: show -- display on screen (default is True) filename -- write to file (default is None) update -- update the coordinates of the atoms to those determined by the structure diagram generator (default is False) usecoords -- don't calculate 2D coordinates, just use the current coordinates (default is False) OASA is used for depiction. Tkinter and Python Imaging Library are required for image display. """ writetofile = filename is not None if not usecoords: # Do the SDG sdg = cdk.layout.StructureDiagramGenerator() sdg.setMolecule(self.Molecule) sdg.generateExperimentalCoordinates() newmol = Molecule(sdg.getMolecule()) if update: for atom, newatom in zip(self.atoms, newmol.atoms): coords = newatom.Atom.getPoint2d() atom.Atom.setPoint3d(javax.vecmath.Point3d( coords.x, coords.y, 0.0)) else: newmol = self if writetofile or show: if writetofile: filedes = None else: filedes, filename = tempfile.mkstemp() # Create OASA molecule if not oasa: errormessage = ("OASA not found, but is required for 2D structure " "depiction. OASA is part of BKChem. " "See installation instructions for more " "information.") raise ImportError, errormessage mol = oasa.molecule() atomnos = [] for newatom in newmol.atoms: if not usecoords: coords = newatom.Atom.getPoint2d() else: coords = newatom.Atom.getPoint3d() if not coords: coords = newatom.Atom.getPoint2d() v = mol.create_vertex() v.charge = newatom.formalcharge v.symbol = _isofact.getElement(newatom.atomicnum).getSymbol() mol.add_vertex(v) v.x, v.y, v.z = coords.x * 30., coords.y * 30., 0.0 for i in range(self.Molecule.getBondCount()): bond = self.Molecule.getBond(i) bo = _revbondtypes[bond.getOrder()] atoms = [self.Molecule.getAtomNumber(x) for x in bond.atoms().iterator()] e = mol.create_edge() e.order = bo if bond.getStereo() == cdk.CDKConstants.STEREO_BOND_DOWN: e.type = "h" elif bond.getStereo() == cdk.CDKConstants.STEREO_BOND_UP: e.type = "w" mol.add_edge(atoms[0], atoms[1], e) mol.remove_unimportant_hydrogens() maxx = max([v.x for v in mol.vertices]) minx = min([v.x for v in mol.vertices]) maxy = max([v.y for v in mol.vertices]) miny = min([v.y for v in mol.vertices]) maxcoord = max(maxx - minx, maxy - miny) for v in mol.vertices: if str(v.x) == "-1.#IND": v.x = minx if str(v.y) == "-1.#IND": v.y = miny fontsize = 16 bondwidth = 6 linewidth = 2 if maxcoord > 270: # 300 - margin * 2 for v in mol.vertices: v.x *= 270. / maxcoord v.y *= 270. / maxcoord fontsize *= math.sqrt(270. / maxcoord) bondwidth *= math.sqrt(270. / maxcoord) linewidth *= math.sqrt(270. / maxcoord) canvas = oasa.cairo_out.cairo_out() canvas.show_hydrogens_on_hetero = True canvas.font_size = fontsize canvas.bond_width = bondwidth canvas.line_width = linewidth canvas.mol_to_cairo(mol, filename) if show: if not tk: errormessage = ("Tkinter or Python Imaging " "Library not found, but is required for image " "display. See installation instructions for " "more information.") raise ImportError, errormessage root = tk.Tk() root.title((hasattr(self, "title") and self.title) or self.__str__().rstrip()) frame = tk.Frame(root, colormap="new", visual='truecolor').pack() image = PIL.open(filename) imagedata = piltk.PhotoImage(image) label = tk.Label(frame, image=imagedata).pack() quitbutton = tk.Button(root, text="Close", command=root.destroy).pack(fill=tk.X) root.mainloop() if filedes: os.close(filedes) os.remove(filename)
def draw(self, show=True, filename=None, update=False, usecoords=False): """Create a 2D depiction of the molecule. Optional parameters: **show** -- display on screen (default is ``True``) **filename** -- write to file (default is ``None``) **update** -- update the coordinates of the atoms This sets the atom coordinates to those determined by the structure diagram generator (default is ``False``) **usecoords** -- use the current coordinates This causes the current coordinates to be used instead of calculating new 2D coordinates (default is ``False``) OASA is used for 2D coordinate generation and depiction. Tkinter and Python Imaging Library are required for image display. """ etab = ob.OBElementTable() if not oasa: errormessage = ( "OASA not found, but is required for 2D structure " "generation and depiction. OASA is part of BKChem. " "See installation instructions for more " "information.") raise ImportError(errormessage) mol = oasa.molecule() for atom in self.atoms: v = mol.create_vertex() v.symbol = etab.GetSymbol(atom.atomicnum) v.charge = atom.formalcharge if usecoords: v.x, v.y, v.z = atom.coords[0] * 30., atom.coords[1] * 30., 0.0 mol.add_vertex(v) for bond in ob.OBMolBondIter(self.OBMol): e = mol.create_edge() e.order = bond.GetBO() if bond.IsHash(): e.type = "h" elif bond.IsWedge(): e.type = "w" mol.add_edge(bond.GetBeginAtomIdx() - 1, bond.GetEndAtomIdx() - 1, e) # I'm sure there's a more elegant way to do the following, but here goes... # let's set the stereochemistry around double bonds self.write("can") # Perceive UP/DOWNness for bond in ob.OBMolBondIter(self.OBMol): ends = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx() if bond.GetBO() == 2: stereobonds = [[ b for b in ob.OBAtomBondIter(self.OBMol.GetAtom(x)) if b.GetIdx() != bond.GetIdx() and (b.IsUp() or b.IsDown()) ] for x in ends] if stereobonds[0] and stereobonds[ 1]: # Needs to be defined at either end if stereobonds[0][0].IsUp() == stereobonds[1][0].IsUp(): # Either both up or both down stereo = oasa.stereochemistry.cis_trans_stereochemistry.SAME_SIDE else: stereo = oasa.stereochemistry.cis_trans_stereochemistry.OPPOSITE_SIDE atomids = [(b[0].GetBeginAtomIdx(), b[0].GetEndAtomIdx()) for b in stereobonds] extremes = [] for id, end in zip(ends, atomids): if end[0] == id: extremes.append(end[1]) else: extremes.append(end[0]) center = mol.get_edge_between(mol.atoms[ends[0] - 1], mol.atoms[ends[1] - 1]) st = oasa.stereochemistry.cis_trans_stereochemistry( center=center, value=stereo, references=(mol.atoms[extremes[0] - 1], mol.atoms[ends[0] - 1], mol.atoms[ends[1] - 1], mol.atoms[extremes[1] - 1])) mol.add_stereochemistry(st) mol.remove_unimportant_hydrogens() if not usecoords: oasa.coords_generator.calculate_coords(mol, bond_length=30) if update: newcoords = [(v.x / 30., v.y / 30., 0.0) for v in mol.vertices] for atom, newcoord in zip(ob.OBMolAtomIter(self.OBMol), newcoords): atom.SetVector(*newcoord) if filename or show: maxx = max([v.x for v in mol.vertices]) minx = min([v.x for v in mol.vertices]) maxy = max([v.y for v in mol.vertices]) miny = min([v.y for v in mol.vertices]) maxcoord = max(maxx - minx, maxy - miny) fontsize = 16 bondwidth = 6 linewidth = 2 if maxcoord > 270: # 300 - margin * 2 for v in mol.vertices: v.x *= 270. / maxcoord v.y *= 270. / maxcoord fontsize *= math.sqrt(270. / maxcoord) bondwidth *= math.sqrt(270. / maxcoord) linewidth *= math.sqrt(270. / maxcoord) if filename: filedes = None else: filedes, filename = tempfile.mkstemp() canvas = oasa.cairo_out.cairo_out() canvas.show_hydrogens_on_hetero = True canvas.font_size = fontsize canvas.bond_width = bondwidth canvas.line_width = linewidth canvas.mol_to_cairo(mol, filename) if show: if not tk: errormessage = ( "Tkinter or Python Imaging " "Library not found, but is required for image " "display. See installation instructions for " "more information.") raise ImportError(errormessage) root = tk.Tk() root.title((hasattr(self, "title") and self.title) or self.__str__().rstrip()) frame = tk.Frame(root, colormap="new", visual='truecolor').pack() image = PIL.open(filename) imagedata = piltk.PhotoImage(image) label = tk.Label(frame, image=imagedata).pack() quitbutton = tk.Button(root, text="Close", command=root.destroy).pack(fill=tk.X) root.mainloop() if filedes: os.close(filedes) os.remove(filename)