Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
 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)
Exemple #5
0
    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)
Exemple #6
0
    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)
Exemple #7
0
    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)