Beispiel #1
0
'''
Created on 2011-1-23

@author: madlee
'''
from kuai.unit import default_units
from math import pi as PI

SPEED_OF_LIGHT = default_units.parse(299792458, 'm/s')
Beispiel #2
0
def setup_model(mols, partable, par):
    if isinstance(mols, Molecule):
        mols = [(mols, 1)]
    elif len(mols) == 2 and isinstance(mols[0], Molecule):
        mols = [mols]
    result = Model()
    result.parameters = par
    result.mols = mols
    result.charges = []
    result.masses = []
    result.coords = []

    result.atomtype = []
    result.group_id = []

    masses_table = partable["atom/mass"]
    type2id = partable["atom/type"]

    amu, _, _ = default_units.parse(1, "amu")
    angerstron, _, _ = default_units.parse(1, "A")

    next_group_id = 0

    for m, n in mols:
        charges = []
        masses = []
        coords = []
        atomtype = []
        group_id = []
        for a in m.atoms:
            if hasattr(a, "partial_charge"):
                charges.append(a.partial_charge)
            else:
                charges.append(0.0)
            if a.type in masses_table:
                masses.append(par[masses_table[a.type]])
            else:
                masses.append(a.weight * amu)
            if hasattr(a, "group_id"):
                group_id.append(a.group_id)

            assert a.type in type2id
            atomtype.append(type2id[a.type])
            coords.append(a.coord.x * angerstron)
            coords.append(a.coord.y * angerstron)
            coords.append(a.coord.z * angerstron)

        result.masses += masses * n
        result.coords += coords * n
        result.charges += charges * n
        result.atomtype += atomtype * n

        group_id_map = {}
        for i in group_id:
            group_id_map[i] = 0
        gid_in_m = [i for i in group_id_map.iterkeys()]
        gid_in_m.sort()
        for i in range(len(gid_in_m)):
            group_id_map[gid_in_m[i]] = i

        for i in range(len(group_id)):
            group_id[i] = group_id_map[group_id[i]]

        for i in range(n):
            result.group_id += [gid + next_group_id for gid in group_id]
            next_group_id += len(gid_in_m)

    if len(result.charges) != len(result.masses):
        del result.charges
    if len(result.group_id) != len(result.masses):
        del result.group_id

    return result
Beispiel #3
0
def read_ppf(file):
    line = file.next().rstrip()
    if line != '#DFF:PPF':
        raise RuntimeError("The input file is not a valid PPF file.")
    line = file.next().rstrip()
    if not line.startswith('#PROTOCOL'):
        raise RuntimeError("The input file is not a valid PPF file.")
    tokens = line.split('=')
    if len(tokens) != 2:
        raise RuntimeError("The input file is not a valid PPF file.")
    
    type = tokens[1].strip()
         
    COULOMB_CONST, _, _ = default_units.parse(8.987551787e9, 'N m2 / C2')
    index = {}
    parameters = [0.0, COULOMB_CONST]

    index['forcefield']={'type':type}

    for line in file:
        tokens = parse_line(line)
        if tokens:
            if tokens[0] == 'E0':
                # Useless term
                pass
                
            elif tokens[0] == 'ATYPE':
                if 'atom/mass' not in index:
                    index['atom/mass'] = {}
                key2par = index['atom/mass']

                key = ' '.join(tokens[1])
                tokens = tokens[2]
                assert len(tokens) == 2
                par = tokens[1]
                par, _, _ = default_units.parse(par, 'amu')
                key2par[key] = len(parameters)
                parameters.append(par)
                
            elif tokens[0] == 'N12_6':
                if 'nonbond/lj12_6' not in index:
                    index['nonbond/lj12_6'] = {}
                key2par = index['nonbond/lj12_6']

                key = ' '.join(tokens[1])
                tokens = tokens[2]
                assert len(tokens) == 2
                key2par[key] = len(parameters)

                par, _, _ = default_units.parse(tokens[0], 'A')
                parameters.append(par)
                par, _, _ = default_units.parse(tokens[1], 'kcal/mol')
                parameters.append(par)
                
            elif tokens[0] == 'ATC':
                if 'atom/charge' not in index:
                    index['atom/charge'] = {}
                key2par = index['atom/charge']
                key = ' '.join(tokens[1])
                tokens = tokens[2]
                assert len(tokens) == 1
                key2par[key] = len(parameters)
                
                par, _, _ = default_units.parse(tokens[0], 'e')
                parameters.append(par)
                
            elif tokens[0] == 'BINC':
                if 'bond/binc' not in index:
                    index['bond/binc'] = {}
                key2par = index['bond/binc']
                
                key = tokens[1]
                assert len(key) == 2
                if key[0] > key[1]:
                    key[0], key[1] = key[1], key[0]
                    reverse=True
                else:
                    reverse=False
                    
                key = ' '.join(key)

                tokens = tokens[2]
                assert len(tokens) == 1
                key2par[key] = len(parameters)
                par, _, _ = default_units.parse(tokens[0], 'e')
                if reverse:
                    parameters.append(-par)
                else:
                    parameters.append(par)

            elif tokens[0] == 'BHARM':
                if 'bond/harmonic' not in index:
                    index['bond/harmonic'] = {}
                key2par = index['bond/harmonic']
                
                key = tokens[1]           
                assert len(key) == 2
                if key[0] > key[1]:
                    key[0], key[1] = key[1], key[0]
                    reverse=True
                else:
                    reverse=False
                    
                key = ' '.join(key)

                tokens = tokens[2]
                assert len(tokens) == 2
                key2par[key] = len(parameters)
                
                par, _, _ = default_units.parse(tokens[0], 'A')
                parameters.append(par)
                par, _, _ = default_units.parse(tokens[1], 'kcal/mol/A2')
                parameters.append(par)

            elif tokens[0] == 'AHARM':
                if 'angle/harmonic' not in index:
                    index['angle/harmonic'] = {}
                key2par = index['angle/harmonic']
                
                key = tokens[1]
                assert len(key) == 3
                if key[0] > key[2]:
                    key[0], key[2] = key[2], key[0]
                    reverse=True
                else:
                    reverse=False
                    
                key = ' '.join([i.strip() for i in key])

                tokens = tokens[2]
                assert len(tokens) == 2
                key2par[key] = len(parameters)
                par, _, _ = default_units.parse(tokens[0], 'deg')
                parameters.append(par)
                par, _, _ = default_units.parse(tokens[1], 'kcal/mol/rad2')
                parameters.append(par)
                
            elif tokens[0] == 'TCOSP':
                if 'torsion/cos_poly5' not in index:
                    index['torsion/cos_poly5'] = {}
                key2par = index['torsion/cos_poly5']
                
                key = tokens[1]
                assert len(key) == 4
                if key[1] > key[2] or key[1] == key[2] and key[0] > key[3]:
                    key[0], key[3] = key[3], key[0]
                    key[1], key[2] = key[2], key[1]
                    reverse=True
                else:
                    reverse=False

                key = ' '.join([i.strip() for i in key])

                tokens = tokens[2]
                assert len(tokens) % 3 == 0
                key2par[key] = len(parameters)
                
                v = [0] * 5
                k = [0] * 6
                for i in range(0, len(tokens), 3):
                    n = int(tokens[i+2]+.1)
                    kI = tokens[i+1]
                    phi = tokens[i+0]
                    if phi > 150:
                        assert abs(phi-180) < 1
                        kI = -kI
                    else:
                        assert abs(phi) < 1
                    if n % 2 == 0:
                        kI = -kI
                    assert v[n] == 0
                    v[n] = 2 * kI
                
                k[0]=v[2]+(v[1]+v[3])/2
                k[1]=0.5*(3*v[3]-v[1])
                k[2]=-v[2]+4*v[4]
                k[3]=-2*v[3]
                k[4]=-4*v[4]
                k[5]=0
                for i in range(0, len(k)):
                    k[i], _, _ = default_units.parse(k[i], 'kcal/mol')
                parameters += k

            elif tokens[0] == 'IBCOS':
                if 'improper_torsion/cos_poly5' not in index:
                    index['improper_torsion/cos_poly5'] = {}
                key2par = index['improper_torsion/cos_poly5']
                
                key = tokens[1]
                assert len(key) == 4
                key = ' '.join(key)

                tokens = tokens[2]
                assert len(tokens) % 3 == 0
                key2par[key] = len(parameters)
                
                v = [0] * 6
                k = [0] * 6
                for i in range(0, len(tokens), 3):
                    n = int(tokens[i+2]+.1)
                    kI = tokens[i+1]
                    phi = tokens[i+0]
                    if phi > 150:
                        assert abs(phi-180) < 1
                        kI = -kI
                    else:
                        assert abs(phi) < 1
                    if n % 2 == 0:
                        kI = -kI
                    assert v[n] == 0
                    v[n] = 2 * kI
                
                k[0]=v[2]+(v[1]+v[3])/2
                k[1]=0.5*(3*v[3]-v[1])
                k[2]=-v[2]+4*v[4]
                k[3]=-2*v[3]
                k[4]=-4*v[4]
                k[5]=0
                for i in range(0, len(k)):
                    k[i], _, _ = default_units.parse(k[i], 'kcal/mol')
                parameters += k
                
            else:
                raise RuntimeError("The function %s is not supported yet." % tokens[0])

    if type == 'AMBER':
        index['forcefield']['scale14/vdw'] = 0.5
        index['forcefield']['scale14/columnb'] = 1 / 1.2
        atomtype, newindex = combine(index['nonbond/lj12_6'], parameters, combine_arithmatic)
        newindex[':columnb-constant:'] = 1
        index['pair-nonbond/lj12_6'] = newindex
        index['atom/type'] = atomtype
        
        index['pair-14/lj12_6'] = scale_vdw(newindex, parameters, 0.5, 1)
        columnb14 = parameters[newindex[':columnb-constant:']] / 1.2
        index['pair-14/lj12_6'][':columnb-constant:'] = len(parameters)
        parameters.append(columnb14)
    else:
        raise RuntimeError("The force field type %s is not supported yet." % type)
        
    return index, parameters