Пример #1
0
def test_vlist_peroxide_dihed_angle_cosine():
    number_of_tests = 50
    for i in xrange(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds = []
        while len(bonds) < 3:
            i0, i1 = [
                int(x) for x in np.random.uniform(low=0, high=4, size=2)
            ]  #pick 2 random atoms
            if i0 == i1 or (i0, i1) in bonds or (i1, i0) in bonds: continue
            if (i0, i1) in system.bonds or (i1, i0) in system.bonds:
                iclist.add_ic(Bond(i0, i1))
                bonds.append((i0, i1))
        mult = np.random.randint(1, 4)
        amp = np.random.normal(0, 1)
        phi0 = np.random.uniform(0, 2 * np.pi)
        vlist.add_term(Cosine(mult, amp, phi0, DihedAngle(0, 1, 2, 3)))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        angle = dihed_angle(system.pos)[0]
        check_energy = 0.5 * amp * (1 - np.cos(mult * (angle - phi0)))
        assert abs(energy - check_energy) < 1e-8
Пример #2
0
def test_vlist_peroxide_dihed_angle_cosine():
    number_of_tests=50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        mult = np.random.randint(1, 4)
        amp = np.random.normal(0, 1)
        phi0 = np.random.uniform(0, 2*np.pi)
        vlist.add_term(Cosine(mult, amp, phi0, DihedAngle(0,1,2,3)))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        angle = dihed_angle(system.pos)[0]
        check_energy = 0.5*amp*(1-np.cos(mult*(angle-phi0)))
        assert abs(energy - check_energy) < 1e-8
Пример #3
0
def test_vlist_peroxide_dihed_cos_chebychev6():
    number_of_tests = 50
    for i in xrange(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds = []
        while len(bonds) < 3:
            i0, i1 = [
                int(x) for x in np.random.uniform(low=0, high=4, size=2)
            ]  #pick 2 random atoms
            if i0 == i1 or (i0, i1) in bonds or (i1, i0) in bonds: continue
            if (i0, i1) in system.bonds or (i1, i0) in system.bonds:
                iclist.add_ic(Bond(i0, i1))
                bonds.append((i0, i1))
        amp = np.random.normal(0, 1)
        sign = np.random.randint(2)
        if sign == 0: sign = -1
        vlist.add_term(Chebychev6(amp, DihedCos(0, 1, 2, 3), sign=sign))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        psi = dihed_angle(system.pos)[0]
        check_energy = 0.5 * amp * (1.0 + sign * np.cos(6 * psi))
        assert abs(energy - check_energy) < 1e-8
Пример #4
0
def test_vlist_peroxide_dihed_cos_chebychev6():
    number_of_tests=50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        amp = np.random.normal(0, 1)
        sign = np.random.randint(2)
        if sign==0: sign = -1
        vlist.add_term(Chebychev6(amp, DihedCos(0,1,2,3), sign=sign))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        psi = dihed_angle(system.pos)[0]
        check_energy = 0.5*amp*(1.0+sign*np.cos(6*psi))
        assert abs(energy - check_energy) < 1e-8
Пример #5
0
def test_zero_dihed_steven():
    pos = np.array([
        [
            3.99364178360816302e+00, 6.30763314754801546e-02,
            -3.46387534695341159e+00
        ],
        [
            8.25853872852823123e+00, -2.56426319334358244e+00,
            2.79913814647939019e-01
        ],
        [
            6.27951244286421861e+00, -1.73747102970232015e+00,
            -2.05686744048685455e+00
        ],
        [
            8.12025850622788603e+00, -6.72445448176343996e-01,
            2.91920676811204993e+00
        ],
    ])
    numbers = np.array([1, 2, 3, 4])
    system = System(numbers, pos)
    fp = ForcePartValence(system)
    fp.add_term(Cosine(3, 0.001, 0.0, DihedAngle(0, 1, 2, 3)))
    gpos = np.zeros(pos.shape)
    fp.compute(gpos)
    # Dihedral is very nearly zero, but not exactly
    assert np.abs(fp.iclist.ictab[0]['value'] -
                  dihed_angle(system.pos)[0]) < 1e-8
    assert np.abs(fp.iclist.ictab[0]['grad']) < 1e-8
    assert not np.isnan(gpos).any()
Пример #6
0
def test_gpos_vtens_dihed_angle_cosine_peroxide():
    system = get_system_peroxide()
    part = ForcePartValence(system)
    part.add_term(Cosine(3, 1.5, 2 * np.pi / 3, DihedAngle(0, 1, 2, 3)))
    print(dihed_angle(system.pos)[0] / np.pi)
    check_gpos_part(system, part)
    check_vtens_part(system, part)
Пример #7
0
def test_iclist_peroxide_dihedral_angle():
    number_of_tests=50
    for i in xrange(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        # The bonds are added randomly to get different situations in the delta list
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        iclist.add_ic(DihedAngle(0,1,2,3))
        dlist.forward()
        iclist.forward()
        assert iclist.ictab[3]['kind']==4 #assert the third ic is DihedralAngle
        assert abs(iclist.ictab[3]['value'] - dihed_angle(system.pos)[0]) < 1e-5
Пример #8
0
def test_iclist_peroxide_dihedral_cos6():
    number_of_tests=50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        system.pos += np.random.normal(0.0, 0.1, system.pos.shape)*angstrom
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        # The bonds are added randomly to get different situations in the delta list
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        iclist.add_ic(DihedCos6(0,1,2,3))
        dlist.forward()
        iclist.forward()
        angle = dihed_angle(system.pos)[0]
        print('psi=%.3f deg:    target=%.6f  value=%.6f' %(angle/deg, np.cos(6*angle), iclist.ictab[3]['value']))
        assert abs(iclist.ictab[3]['value'] - np.cos(6*angle)) < 1e-5
Пример #9
0
def test_vlist_peroxide_dihed_angle():
    number_of_tests=50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        vlist.add_term(Harmonic(1.5, 0.1 , DihedAngle(0,1,2,3)))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        angle = dihed_angle(system.pos)[0]
        check_energy = 0.5*1.5*(angle-0.1)**2
        assert abs(energy - check_energy) < 1e-8
Пример #10
0
def test_vlist_peroxide_dihed_angle():
    number_of_tests=50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        vlist = ValenceList(iclist)
        bonds=[]
        while len(bonds)<3:
            i0, i1 = [int(x) for x in np.random.uniform(low=0,high=4,size=2)] #pick 2 random atoms
            if i0==i1 or (i0,i1) in bonds or (i1,i0) in bonds: continue
            if (i0,i1) in system.bonds or (i1,i0) in system.bonds:
                iclist.add_ic(Bond(i0,i1))
                bonds.append((i0,i1))
        vlist.add_term(Harmonic(1.5, 0.1 , DihedAngle(0,1,2,3)))
        dlist.forward()
        iclist.forward()
        energy = vlist.forward()
        # calculate energy manually
        angle = dihed_angle(system.pos)[0]
        check_energy = 0.5*1.5*(angle-0.1)**2
        assert abs(energy - check_energy) < 1e-8
Пример #11
0
def test_iclist_peroxide_dihedral_angle():
    number_of_tests = 50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        # The bonds are added randomly to get different situations in the delta list
        bonds = []
        while len(bonds) < 3:
            i0, i1 = [
                int(x) for x in np.random.uniform(low=0, high=4, size=2)
            ]  #pick 2 random atoms
            if i0 == i1 or (i0, i1) in bonds or (i1, i0) in bonds: continue
            if (i0, i1) in system.bonds or (i1, i0) in system.bonds:
                iclist.add_ic(Bond(i0, i1))
                bonds.append((i0, i1))
        iclist.add_ic(DihedAngle(0, 1, 2, 3))
        dlist.forward()
        iclist.forward()
        assert iclist.ictab[3][
            'kind'] == 4  #assert the third ic is DihedralAngle
        assert abs(iclist.ictab[3]['value'] -
                   dihed_angle(system.pos)[0]) < 1e-5
Пример #12
0
def test_iclist_peroxide_dihedral_cos6():
    number_of_tests = 50
    for i in range(number_of_tests):
        system = get_system_peroxide()
        system.pos += np.random.normal(0.0, 0.1, system.pos.shape) * angstrom
        dlist = DeltaList(system)
        iclist = InternalCoordinateList(dlist)
        # The bonds are added randomly to get different situations in the delta list
        bonds = []
        while len(bonds) < 3:
            i0, i1 = [
                int(x) for x in np.random.uniform(low=0, high=4, size=2)
            ]  #pick 2 random atoms
            if i0 == i1 or (i0, i1) in bonds or (i1, i0) in bonds: continue
            if (i0, i1) in system.bonds or (i1, i0) in system.bonds:
                iclist.add_ic(Bond(i0, i1))
                bonds.append((i0, i1))
        iclist.add_ic(DihedCos6(0, 1, 2, 3))
        dlist.forward()
        iclist.forward()
        angle = dihed_angle(system.pos)[0]
        print('psi=%.3f deg:    target=%.6f  value=%.6f' %
              (angle / deg, np.cos(6 * angle), iclist.ictab[3]['value']))
        assert abs(iclist.ictab[3]['value'] - np.cos(6 * angle)) < 1e-5
Пример #13
0
def load_rotscan_g03log(fn_log, top_indexes=None):
    """Load the torsional potential from a Gaussian 03 log/output file.

       Argument:
        | ``fn_log`` -- The filename of the gaussian output.

       Optional argument:
        | ``top_indexes`` -- The atom indexes that define the rotor. These do
                             not have to include the atoms that define the
                             rotational axis. When not given, an attempt is made
                             to derive this information from the dihedral angle
                             used for the scan.
    """
    # find the line that specifies the dihedral angle
    with open(fn_log) as f:
        found_modredundant = False
        for line in f:
            if line.startswith(" The following ModRedundant input section has been read:"):
                found_modredundant = True
                break
        if not found_modredundant:
            raise IOError("Could not find the ModRedundant section in the log file.")

        dihedral = None
        num_geoms = 0
        for line in f:
            line = line.strip()
            if len(line) == 0:
                break
            else:
                words = line.split()
                if words[0] == "D" and (words[5] == "S" or words[5] == "F"):
                    if dihedral is None:
                        dihedral = list(int(word)-1 for word in words[1:5])
                    else:
                        raise IOError("Found multiple dihedral angle scan, which is not supported.")

        if dihedral is None:
            raise IOError("Could not find the dihedral angle of the rotational scan.")

        # load all the energies and compute the corresponding angles
        energies = []
        angles = []
        geometries = []
        for line in f:
            if line.startswith("                          Input orientation:") or \
               line.startswith("                         Standard orientation:"):
                # read the molecule
                numbers = []
                last_coordinates = []
                ## skip four lines
                for i in xrange(4):
                    f.next()
                # read atoms
                for line in f:
                    if line.startswith(" -----"):
                        break
                    words = line.split()
                    numbers.append(int(words[1]))
                    last_coordinates.append((float(words[3]), float(words[4]), float(words[5])))
            if line.startswith(" SCF Done:"):
                # read the energy
                last_energy = float(line[line.find("=")+1:].split()[0])
            if line.startswith("    -- Stationary point found."):
                # store last emergy and geometry in list
                energies.append(last_energy)
                last_coordinates = np.array(last_coordinates)*angstrom
                geometries.append(last_coordinates)
                angles.append(dihed_angle(last_coordinates[dihedral])[0])

        if len(energies) == 0:
            raise IOError("Could not find any stationary point")

        if top_indexes is None:
            # Define the molecular geometry that is used in the constructor of
            # RotScan to detect the top.
            from molmod.molecules import Molecule as BaseMolecule
            molecule = BaseMolecule(numbers, geometries[0])
        else:
            molecule = None
        result = RotScan(
            dihedral, molecule, top_indexes,
            np.array([angles, energies])
        )
        result.geometries = np.array(geometries)
        return result
Пример #14
0
#!/usr/bin/env python

import argparse
import molmod as mm
import numpy as np
import mdtraj as md


def eval_pplane(atoms_xyz):
    return mm.opbend_dist(atoms_xyz)[0] / mm.angstrom


CV_KIND_DICT = {
    'BOND': lambda atoms_xyz: mm.bond_length(atoms_xyz)[0] / mm.angstrom,
    'ANGLE': lambda atoms_xyz: mm.bend_angle(atoms_xyz)[0] / mm.deg,
    'DIHEDRAL': lambda atoms_xyz: mm.dihed_angle(atoms_xyz)[0] / mm.deg,
    'PPLANE': lambda atoms_xyz: eval_pplane(np.roll(atoms_xyz, -3))
}


MULTICV_KIND_DICT = {'MBOND': (2, 'BOND'),
                     'MANGLE': (3, 'ANGLE'),
                     'MDIHEDRAL': (4, 'DIHEDRAL'),
                     'MPPLANE': (4, 'PPLANE')}


def get_center(xyz, indices):
    return np.mean(np.take(xyz, indices, axis=0), axis=0)


def get_centers(xyz, centers):
Пример #15
0
def load_rotscan_g03log(fn_log, top_indexes=None):
    """Load the torsional potential from a Gaussian 03 log/output file.

       Argument:
        | ``fn_log`` -- The filename of the gaussian output.

       Optional argument:
        | ``top_indexes`` -- The atom indexes that define the rotor. These do
                             not have to include the atoms that define the
                             rotational axis. When not given, an attempt is made
                             to derive this information from the dihedral angle
                             used for the scan.
    """
    # find the line that specifies the dihedral angle
    with open(fn_log) as f:
        found_modredundant = False
        for line in f:
            if line.startswith(" The following ModRedundant input section has been read:"):
                found_modredundant = True
                break
        if not found_modredundant:
            raise IOError("Could not find the ModRedundant section in the log file.")

        dihedral = None
        num_geoms = 0
        for line in f:
            line = line.strip()
            if len(line) == 0:
                break
            else:
                words = line.split()
                if words[0] == "D" and (words[5] == "S" or words[5] == "F"):
                    if dihedral is None:
                        dihedral = list(int(word)-1 for word in words[1:5])
                    else:
                        raise IOError("Found multiple dihedral angle scan, which is not supported.")

        if dihedral is None:
            raise IOError("Could not find the dihedral angle of the rotational scan.")

        # load all the energies and compute the corresponding angles
        energies = []
        angles = []
        geometries = []
        for line in f:
            if line.startswith("                          Input orientation:") or \
               line.startswith("                         Standard orientation:"):
                # read the molecule
                numbers = []
                last_coordinates = []
                ## skip four lines
                for i in xrange(4):
                    f.next()
                # read atoms
                for line in f:
                    if line.startswith(" -----"):
                        break
                    words = line.split()
                    numbers.append(int(words[1]))
                    last_coordinates.append((float(words[3]), float(words[4]), float(words[5])))
            if line.startswith(" SCF Done:"):
                # read the energy
                last_energy = float(line[line.find("=")+1:].split()[0])
            if line.startswith("    -- Stationary point found."):
                # store last emergy and geometry in list
                energies.append(last_energy)
                last_coordinates = np.array(last_coordinates)*angstrom
                geometries.append(last_coordinates)
                angles.append(dihed_angle(last_coordinates[dihedral])[0])

        if len(energies) == 0:
            raise IOError("Could not find any stationary point")

        if top_indexes is None:
            # Define the molecular geometry that is used in the constructor of
            # RotScan to detect the top.
            from molmod.molecules import Molecule as BaseMolecule
            molecule = BaseMolecule(numbers, geometries[0])
        else:
            molecule = None
        result = RotScan(
            dihedral, molecule, top_indexes,
            np.array([angles, energies])
        )
        result.geometries = np.array(geometries)
        return result
Пример #16
0
def test_iclist_mil53_dihedral_angles():
    system = get_system_mil53()
    dlist = DeltaList(system)
    iclist = InternalCoordinateList(dlist)
    ic_values = []
    gpos = np.zeros(system.pos.shape)
    forbidden_dihedrals = [
        ["O_HY", "AL", "O_HY", "AL"],
        ["O_HY", "AL", "O_HY", "H_HY"],
        ["O_CA", "AL", "O_CA", "C_CA"],
    ]
    for i1, i2 in system.bonds:
        # Add bonds here to avoid that all ic signs are +1
        iclist.add_ic(Bond(i2, i1))
        for i0 in system.neighs1[i1]:
            if i0 == i2: continue
            for i3 in system.neighs1[i2]:
                if i3 == i1: continue
                # Compute using molmod
                delta0 = system.pos[i0] - system.pos[i1]
                delta1 = system.pos[i2] - system.pos[i1]
                delta2 = system.pos[i3] - system.pos[i2]
                system.cell.mic(delta0)
                system.cell.mic(delta1)
                system.cell.mic(delta2)
                pos = np.zeros((4, 3))
                pos[0] = system.pos[i1] + delta0
                pos[1] = system.pos[i1]
                pos[2] = system.pos[i1] + delta1
                pos[3] = pos[2] + delta2
                phi0, dphi0 = dihed_angle(pos, deriv=1)
                # Compute value using yaff
                iic = iclist.add_ic(DihedAngle(i0, i1, i2, i3))
                ic = iclist.ictab[iic]
                dlist.forward()
                iclist.forward()
                phi1 = ic['value']
                if np.abs(phi1 - phi0) > 1e-8:
                    raise AssertionError(
                        "DihedralAngle(%d,%d,%d,%d): molmod "
                        "value = %12.8f yaff value = %12.8f diff = %12.2e" %
                        (i0, i1, i2, i3, phi0, phi1, phi0 - phi1))
                # Compute derivative using yaff
                gpos[:] = 0.0
                ic['grad'] = 1.0
                iclist.back()
                dlist.back(gpos, None)
                # Derivative of DihedCos fails in these cases, and DihedAngle
                # derivatives are base on this
                types = [
                    system.get_ffatype(i0),
                    system.get_ffatype(i1),
                    system.get_ffatype(i2),
                    system.get_ffatype(i3)
                ]
                if types in forbidden_dihedrals or types[::
                                                         -1] in forbidden_dihedrals:
                    continue
                ddiff = gpos[[i0, i1, i2, i3]] - dphi0
                if np.any(np.abs(ddiff) > 1e-6):
                    raise AssertionError(
                        "DihedralAngle(%d,%d,%d,%d): largest "
                        "absolute derivative deviation =  %12.2e" %
                        (i0, i1, i2, i3, np.amax(np.abs(ddiff))))