示例#1
0
def calcBonds(
    coords, symbols, dim=None, maxAtomRadius=None, bondMargin=0.2, boxMargin=1.0
):
    """Calculate the bonds for the fragments. This is done at the start when the only coordinates
    are those in the fragment.
    """
    close = closeAtoms(coords, symbols, dim, maxAtomRadius, boxMargin)
    v1 = []
    v2 = []
    for idxAtom1, idxAtom2 in close:
        v1.append(coords[idxAtom1])
        v2.append(coords[idxAtom2])

    distances = xyz_core.distance(np.array(v1), np.array(v2), dim=dim)
    bonds = []
    for i, (idxAtom1, idxAtom2) in enumerate(close):
        bond_length = bondLength(symbols[idxAtom1], symbols[idxAtom2])
        if bond_length < 0:
            continue
        logger.debug(
            "Dist:length {1}({0})-{3}({2}) {4} {5}".format(
                symbols[idxAtom1],
                idxAtom1,
                symbols[idxAtom2],
                idxAtom2,
                distances[i],
                bond_length,
            )
        )
        if bond_length - bondMargin < distances[i] < bond_length + bondMargin:
            bonds.append((idxAtom1, idxAtom2))
    # We sort the bonds on return so that results are deterministic and can be tested
    return sorted(bonds)
示例#2
0
 def _calcRadius(self):
     """Calculate a simple size metric of the block so that we can screen for whether
     two blocks are within touching distance
     Assumes centroid already calculated
     """
     distances = []
     self._maxAtomRadius = 0.0
     for f in self.fragments:
         for coord in f.iterCoord():
             distances.append(xyz_core.distance(self._centroid, coord))
             self._maxAtomRadius = max(f.maxAtomRadius(),
                                       self._maxAtomRadius)
     assert distances
     imax = np.argmax(distances)
     dist = distances[imax]
     # Add on the radius of the largest atom
     self._radius = dist + self.maxAtomRadius()
     return
示例#3
0
    def setEndGroups(self, endGroupTypes, endGroups, capAtoms, dihedralAtoms,
                     uwAtoms):
        self._endGroups = []
        self._maxBonds = {}
        self._endGroupBonded = {}
        for i, e in enumerate(endGroups):
            eg = ab_endgroup.EndGroup()
            eg.fragment = self
            eg._endGroupType = endGroupTypes[i]
            eg.fragmentEndGroupIdx = e
            eg.fragmentCapIdx = capAtoms[i]
            eg.fragmentDihedralIdx = dihedralAtoms[i]
            eg.fragmentUwIdx = uwAtoms[i]
            eg.capBondLength = xyz_core.distance(
                self._coords[eg.fragmentCapIdx],
                self._coords[eg.fragmentEndGroupIdx])
            if eg.type() not in self._maxBonds:
                self._maxBonds[eg.type()] = None
            if eg.type() not in self._endGroupBonded:
                self._endGroupBonded[eg.type()] = 0

            # sanity check
            assert (eg.fragmentCapIdx in self._bonded[eg.fragmentEndGroupIdx]
                    ), "capAtom {0} is not bonded to endGroup {1}".format(
                        eg.fragmentCapIdx, eg.fragmentEndGroupIdx)
            if eg.fragmentDihedralIdx != -1:
                assert (
                    eg.fragmentDihedralIdx
                    in self._bonded[eg.fragmentEndGroupIdx]
                ), "dihedral Atom {0} is not bonded to endGroup {1}".format(
                    eg.fragmentDihedralIdx, eg.fragmentEndGroupIdx)
            if eg.fragmentUwIdx != -1:
                assert (eg.fragmentUwIdx
                        in self._bonded[eg.fragmentEndGroupIdx]
                        ), "uwAtom {0} is not bonded to endGroup {1}".format(
                            eg.fragmentUwIdx, eg.fragmentEndGroupIdx)
            self._endGroups.append(eg)
        # sanity check - make sure no endGroup is the cap Atom for another endGroup
        eg = set([e.fragmentEndGroupIdx for e in self._endGroups])
        caps = set([e.fragmentCapIdx for e in self._endGroups])
        assert (len(eg.intersection(caps)) == 0
                ), "Cap atom for one endGroup is another endGroup!"
        return
示例#4
0
def calcBondsHACK(coords, symbols, bondMargin=0.2):
    """HACK FOR NETWORK"""
    bonds = []
    for i, coord1 in enumerate(coords):
        symbol1 = symbols[i]
        for j, coord2 in enumerate(coords):
            if j < i:
                continue
            symbol2 = symbols[j]
            dist = xyz_core.distance(coord1, coord2)
            if symbol1 == "j" and symbol2 == "C":
                bond_length = 4.31
            elif symbol2 == "j" and symbol1 == "C":
                bond_length = 4.31
            else:
                bond_length = bondLength(symbol1, symbol2)
            # print "GOT ",symbol1,symbol2,bond_length, dist
            if bond_length - bondMargin < dist < bond_length + bondMargin:
                # print "BONDING"
                bonds.append((i, j))
    return bonds
示例#5
0
    def _calcRadius(self):
        """
        Calculate a simple size metric of the block so that we can screen for whether
        two blocks are within touching distance

        First try a simple approach with a loop just to get a feel for things
        - Find the largest distance between any atom and the center of geometry
        - Get the covalent radius of that atom
        - return that distance + radius + buffer

        Should move to use scipy as detailed here:
        http://stackoverflow.com/questions/6430091/efficient-distance-calculation-between-n-points-and-a-reference-in-numpy-scipy
        """
        distances = [
            xyz_core.distance(self._centroid, coord) for coord in self._coords
        ]
        imax = np.argmax(distances)
        dist = distances[imax]
        self._radius = dist + self.maxAtomRadius(
        )  # Add on the radius of the largest atom
        return
示例#6
0
def writeCml(
    cmlFilename,
    coords,
    symbols,
    bonds=None,
    atomTypes=None,
    cell=None,
    pruneBonds=False,
    prettyPrint=False,
):

    assert len(coords) == len(symbols)
    if pruneBonds:
        assert cell is not None
        pcoords = []  # need to save periodic coordinates

    root = ET.Element("molecule")
    root.attrib["xmlns"] = "http://www.xml-cml.org/schema"
    root.attrib["xmlns:cml"] = "http://www.xml-cml.org/dict/cml"
    root.attrib["xmlns:units"] = "http://www.xml-cml.org/units/units"
    root.attrib["xmlns:xsd"] = "http://www.w3c.org/2001/XMLSchema"
    root.attrib["xmlns:iupac"] = "http://www.iupac.org"
    root.attrib["id"] = "mymolecule"

    if cell is not None:
        # First set up the cell
        crystal = ET.SubElement(root, "crystal")

        crystalANode = ET.SubElement(crystal, "scalar")
        crystalBNode = ET.SubElement(crystal, "scalar")
        crystalCNode = ET.SubElement(crystal, "scalar")
        crystalAlphaNode = ET.SubElement(crystal, "scalar")
        crystalBetaNode = ET.SubElement(crystal, "scalar")
        crystalGammaNode = ET.SubElement(crystal, "scalar")

        crystalANode.attrib["title"] = "a"
        crystalBNode.attrib["title"] = "b"
        crystalCNode.attrib["title"] = "c"
        crystalAlphaNode.attrib["title"] = "alpha"
        crystalBetaNode.attrib["title"] = "beta"
        crystalGammaNode.attrib["title"] = "gamma"

        crystalANode.attrib["units"] = "units:angstrom"
        crystalBNode.attrib["units"] = "units:angstrom"
        crystalCNode.attrib["units"] = "units:angstrom"
        crystalAlphaNode.attrib["units"] = "units:degree"
        crystalBetaNode.attrib["units"] = "units:degree"
        crystalGammaNode.attrib["units"] = "units:degree"

        crystalANode.text = str(cell[0])
        crystalBNode.text = str(cell[1])
        crystalCNode.text = str(cell[2])

        # Only support orthorhombic? cells
        crystalAlphaNode.text = "90"
        crystalBetaNode.text = "90"
        crystalGammaNode.text = "90"
    if atomTypes:
        assert len(atomTypes) == len(coords)
        # Need to collate atomTypes - sorted to ensure consistency for testing
        for atype in sorted(set(atomTypes)):
            atomTypeNode = ET.SubElement(root, "atomType")
            atomTypeNode.attrib["name"] = atype
            atomTypeNode.attrib["title"] = atype
    # Now atom data
    atomArrayNode = ET.SubElement(root, "atomArray")
    for i, coord in enumerate(coords):
        atomNode = ET.SubElement(atomArrayNode, "atom")
        atomNode.attrib["id"] = "a{0}".format(i)
        atomNode.attrib["elementType"] = symbols[i]
        if cell is not None:
            coord, _ = xyz_core.wrapCoord3(coord, cell, center=False)
            if pruneBonds:
                pcoords.append(coord)
        x, y, z = coord
        atomNode.attrib["x3"] = "{:.12}".format(x)
        atomNode.attrib["y3"] = "{:.12}".format(y)
        atomNode.attrib["z3"] = "{:.12}".format(z)
        if atomTypes:
            # Now add atomType as child node referring to the atomType
            atomTypeNode = ET.SubElement(atomNode, "atomType")
            atomTypeNode.attrib["ref"] = atomTypes[i]
    if len(bonds):
        # Now do bonds
        if pruneBonds:
            # Hack to get vis working
            # Calculate all bond distances
            distances = xyz_core.distance(
                [pcoords[b1] for b1, b2 in bonds], [pcoords[b2] for b1, b2 in bonds]
            )

            # Complete hack - just see if it's longer then 0.5 the cell A distance - assumes cubic cell
            bonds = [b for i, b in enumerate(bonds) if distances[i] <= cell[0] * 0.5]

        bondArrayNode = ET.SubElement(root, "bondArray")
        for b in bonds:
            bondNode = ET.SubElement(bondArrayNode, "bond")
            bondNode.attrib["atomRefs2"] = "a{0} a{1}".format(b[0], b[1])
            bondNode.attrib["order"] = "1"

    cmlFilename = os.path.abspath(cmlFilename)
    if prettyPrint:
        estring = xml.dom.minidom.parseString(ET.tostring(root))
        with open(cmlFilename, "w") as w:
            w.write(estring.toprettyxml())
    else:
        tree = ET.ElementTree(root)
        tree.write(cmlFilename, encoding="utf-8", xml_declaration=True)
    return cmlFilename