예제 #1
0
def test_user_can_pass_information_from_mol_to_mol():
    reference = Molecule(atoms)
    ref = reference.get_number_of_atoms()
    molecule = Molecule(symbols=reference)
    nat = molecule.get_number_of_atoms()
    assert nat == ref
    positions = molecule.get_positions()
    assert positions[0][2] == 0
    assert positions[1][2] == 1
    assert positions[2][2] == 2
    numbers = molecule.get_array("numbers")
    assert numbers[0] == 1
예제 #2
0
def matchSubstrates(
    bonds: np.ndarray,
    new: Molecule,
    bondsNewSub: np.ndarray,
    old: Molecule,
    bondsOldSub,
    center: np.ndarray,
) -> np.ndarray:
    """Match substrates by root mean squared deviation measure."""

    # check is central atom given
    centered = False
    count = 1
    if center is not None:
        centered = True
        count = 2

    newnat = new.get_number_of_atoms()
    newxyz = np.zeros(shape=(newnat, 3), dtype=np.float64)
    newxyz = new.get_positions()

    oldnat = old.get_number_of_atoms()
    oldxyz = np.zeros(shape=(oldnat, 3), dtype=np.float64)
    oldxyz = old.get_positions()

    # shift to first atom of old substrate
    shift = np.zeros(shape=(3, ), dtype=np.float64)
    shift = oldxyz[0, :]
    oldShift = shift
    oldxyz2 = np.zeros(shape=(oldnat, 3), dtype=np.float64)
    for i in range(oldnat):
        oldxyz2[i][:] = oldxyz[i][:] - shift

    # shift to first atom of new substrate
    shift = newxyz[0, :]
    newxyz2 = np.zeros(shape=(newnat, 3), dtype=np.float64)
    for i in range(newnat):
        newxyz2[i][:] = newxyz[i][:] - shift

    # covalent bonding partner in old substrate
    covOld = len(bondsOldSub[0][:])

    # covalent bonding partner in new substrate
    covNew = len(bondsNewSub[0][:])

    # Check for linear moleule case
    if covNew != 1:
        isNotLinear = True
    else:
        isNotLinear = False

    covOld += count
    covNew += count

    # get structures for RMSD alignment
    shiftOldSub = np.zeros(shape=(covOld, 3), dtype=np.float64)
    shiftOldSub[0, :] = oldxyz2[0, :]
    shiftNewSub = np.zeros(shape=(covNew, 3), dtype=np.float64)
    shiftNewSub[0, :] = newxyz2[0, :]

    # shift old substrate
    i = 0
    for j in range(len(bondsOldSub[0][:])):
        i += 1
        k = bondsOldSub[0][j]
        shiftOldSub[i, :] = oldxyz2[k, :]

    # shift new substrate
    i = 0
    for j in range(len(bondsNewSub[0][:])):
        i += 1
        k = bondsNewSub[0][j]
        shiftNewSub[i, :] = newxyz2[k, :]

    if centered:
        indexOld = covOld - 1
        indexNew = covNew - 1
        shiftOldSub[indexOld, :] = center - oldShift
        shiftNewSub[indexNew][:] = 0
        distRef = distance.euclidean(shiftOldSub[0, :],
                                     shiftOldSub[indexOld, :])
        getNewSubstrateCenter(indexNew, shiftNewSub, distRef)

    bdim = np.minimum(covOld, covNew)

    if bdim >= 3:
        bdim = 3
        b1xyz = np.zeros(shape=(bdim, 3), dtype=np.ndarray)
        b2xyz = np.zeros(shape=(bdim, 3), dtype=np.ndarray)
        indexOld = covOld - 1
        indexNew = covNew - 1
        b1xyz[0][:] = shiftOldSub[0][:]
        b1xyz[1][:] = shiftOldSub[1][:]
        b1xyz[2][:] = shiftOldSub[indexOld][:]
        b2xyz[0][:] = shiftNewSub[0][:]
        b2xyz[1][:] = shiftNewSub[1][:]
        b2xyz[2][:] = shiftNewSub[indexNew][:]
    else:
        bdim = 2
        b1xyz = np.zeros(shape=(bdim, 3), dtype=np.ndarray)
        b2xyz = np.zeros(shape=(bdim, 3), dtype=np.ndarray)
        indexOld = covOld - 1
        indexNew = covNew - 1
        b1xyz[0][:] = shiftOldSub[0][:]
        b1xyz[1][:] = shiftOldSub[indexOld][:]
        b2xyz[0][:] = shiftNewSub[0][:]
        b2xyz[1][:] = shiftNewSub[indexNew][:]

    tmpxyz = np.zeros(shape=(newnat, 3), dtype=np.float64)
    outxyz = np.zeros(shape=(newnat, 3), dtype=np.float64)

    if isNotLinear:
        u = np.zeros(shape=(3, 3), dtype=np.float64)
        # get RMSD value and rotation matrix
        _, u = rmsd(bdim, b2xyz, b1xyz)
        tmpxyz = np.matmul(u.T, newxyz2[:][0:newnat].T)
        # shift
        for i in range(newnat):
            outxyz[i, :] = tmpxyz.T[i, :] + oldShift

        return outxyz

    tmpxyz = newxyz2[:][0:newnat]
    # shift
    for i in range(newnat):
        outxyz[i, :] = tmpxyz[i, :] + oldShift

    return outxyz
예제 #3
0
def test_user_can_get_number_of_atoms():
    reference = Molecule(atoms)
    nat = reference.get_number_of_atoms()
    assert nat == 3
예제 #4
0
def exchangeSubstructure(
    n: int,
    center: int,
    subnr: int,
    bonds,
    ref: Molecule,
    newsub: Molecule,
    newSubBonds,
    name: str,
    rotate: int,
    exclude: bool,
) -> Molecule:
    """Exchange substructure (subnr) from ref with substrate."""

    # setup initial complex
    refxyz = ref.get_positions()
    refat = ref.get_atomic_numbers()
    refnat = ref.get_number_of_atoms()

    # match new and old substrate
    newat = newsub.get_atomic_numbers()
    newnat = newsub.get_number_of_atoms()

    # extract coordinates of central atom
    centralAtom = refxyz[center, :]

    mol = Molecule()
    for i in range(len(bonds[center])):
        if i == subnr:
            path = np.zeros(shape=(n, ), dtype=np.int32)
            # set all elements to -1
            path.fill(-1)
            partner = bonds[center][i]
            count = Counter()  # type: ignore
            count["step"] = -1
            getSubstructures(n, bonds, center, partner, path, count=count)
            # get rid of -1 elements
            path = [x for x in path if x != -1]
            path = np.array(path)
            # create molecule from given path
            oldsub = getSubstructureFromPath(ref, path)
            # get all bonding partner
            oldSubBonds = oldsub.get_bonds(partner="X")
            outxyz = matchSubstrates(
                bonds,
                newsub,
                newSubBonds,
                oldsub,
                oldSubBonds,
                centralAtom,
            )

            # atoms from complex excluding old substrate
            atoms = []
            for j in range(refnat):
                if j in path:
                    continue
                atom = Atom(symbol=refat[j], position=refxyz[j, :])
                atoms.append(atom)

            # atoms from new substrate

            # Should we rotate the substrate around covalent bond?
            if rotate:
                theta = rotate
                origin = refxyz[center, :]
                partner = outxyz[0, :]
                outxyz2 = np.zeros(shape=outxyz.shape, dtype=np.float64)
                # reference shift
                refShift = getRodriguezRotation(partner, origin, partner,
                                                theta)
                shift = outxyz[0, :] - refShift
                for j in range(newnat):
                    outxyz2[j, :] = getRodriguezRotation(
                        outxyz[j, :],
                        origin,
                        partner,
                        theta,
                    )
                    outxyz2[j, :] += shift

                    atom = Atom(symbol=newat[j], position=outxyz2[j, :])
                    atoms.append(atom)
            else:
                for j in range(newnat):
                    atom = Atom(symbol=newat[j], position=outxyz[j, :])
                    atoms.append(atom)

            # create molecule from atoms
            mol = Molecule(symbols=atoms)

            # write new structure in xyz format
            mol.writeMolecule(name + ".xyz")

            # write constrain file
            refnat = ref.get_number_of_atoms()
            oldnat = oldsub.get_number_of_atoms()
            nat = refnat - oldnat
            writeTransitionMetalConstrains(nat, newnat, newSubBonds, exclude)
            return mol

    return mol