Пример #1
0
def LoadFragmentFile(path, ff):
    file_data = list(ix.LoadFile(path.expanduser()))
    if file_data.count("MOLECULE") != 1:
        raise InputError("Expect only one molecule per file")
    if file_data[0] != "MOLECULE":
        raise InputError("Expected MOLECULE block")
    if file_data.count("FRAGMENT") != file_data.count("OVERLAP"):
        raise InputError("Should have same number of fragment and overlaps")

    if "END" in file_data[1:4]:
        raise InputError("Missing input files")
    coord_path = path.parent / file_data[1].strip()
    param_path = path.parent / file_data[2].strip()
    detail_path = path.parent / file_data[3].strip()

    mol = LoadParameterisedMolecule(coord_path, param_path, ff, detail_path)

    fragments = []
    current_block = None
    frag = []
    overlap = []
    for line in file_data:
        if line == "END":
            if current_block == "OVERLAP":
                frag = ix.VecAtom(frag)
                overlap = ix.VecAtom(overlap)
                fragments.append(ix.Fragment(mol, frag, overlap))
                frag = []
                overlap = []
            current_block = None
        elif line in ["MOLECULE", "FRAGMENT", "OVERLAP"]:
            current_block = line
        elif current_block == "FRAGMENT":
            frag.extend(mol.GetAtomTag(x) for x in map(int, line.split()))
        elif current_block == "OVERLAP":
            overlap.extend(mol.GetAtomTag(x) for x in map(int, line.split()))

    return mol, fragments
Пример #2
0
def LoadITPFile(path, ff, details=None):
    mol = ix.Molecule(path.stem)

    bondtype = ix.BondType.Harmonic
    angletype = ix.AngleType.Harmonic
    impropertype = ix.DihedralType.Improper
    propertype = ix.DihedralType.Proper

    current_block = None
    for line in ix.LoadFile(path.expanduser(), comment=";"):
        if "[" in line:
            data = line.split()
            current_block = data[1]
        elif "#" in line:
            current_block = None
        elif current_block == "atoms":
            data = line.split()
            atom = mol.NewAtom()
            atom.SetTag(int(data[0]))
            atom.SetName(data[4])
            atom.SetType(ff.GetAtomType(data[1]))
            atom.SetPartialCharge(float(data[6]))
            atom.SetElement(atom.GetType().GetElement())
        elif current_block == "bonds":
            data = line.split()
            bond = mol.NewBond(mol.GetAtomTag(int(data[0])),
                               mol.GetAtomTag(int(data[1])))
            if data[-1].startswith("gb"):
                bond.SetType(
                    ff.GetBondType(bondtype, int(data[-1].split("_")[1])))
        elif current_block == "angles":
            data = line.split()
            a1 = mol.GetAtomTag(int(data[0]))
            a2 = mol.GetAtomTag(int(data[1]))
            a3 = mol.GetAtomTag(int(data[2]))
            angle = mol.GetAngle(mol.GetAtomTag(int(data[0])),
                                 mol.GetAtomTag(int(data[1])),
                                 mol.GetAtomTag(int(data[2])))
            if not angle:
                raise IndexError("No angle found: {}-{}-{}".format(*data[:3]))
            if data[-1].startswith("ga"):
                ty = ff.GetAngleType(angletype, int(data[-1].split("_")[1]))
                angle.SetType(ty)
        elif current_block == "dihedrals":
            data = line.split()
            a = mol.GetAtomTag(int(data[0]))
            b = mol.GetAtomTag(int(data[1]))
            c = mol.GetAtomTag(int(data[2]))
            d = mol.GetAtomTag(int(data[3]))
            if mol.HasDihedral(a, b, c, d):
                dihedral = mol.GetDihedral(a, b, c, d)
            else:
                dihedral = mol.NewDihedral(a, b, c, d)
            if data[-1].startswith("gi"):
                dihedral.AddType(
                    ff.GetDihedralType(impropertype,
                                       int(data[-1].split("_")[1])))
            elif data[-1].startswith("gd"):
                dihedral.AddType(
                    ff.GetDihedralType(propertype,
                                       int(data[-1].split("_")[1])))

    if details is not None:
        LoadIXDFile(details, mol)
    return mol
Пример #3
0
def LoadIXDFile(path, mol):
    set_implicits = []
    for line in ix.LoadFile(path.expanduser()):
        line = line.split()
        l = list(map(int, line[1:]))
        if line[0] == "ATOM":
            atom = mol.GetAtomTag(l[0])
            if not atom:
                raise IndexError("Unknown atom tag: {}".format(l[0]))
            atom.SetFormalCharge(l[1])
            atom.SetImplicitCount(l[2])
            set_implicits.append(l[0])
        elif line[0] == "BOND":
            bond = mol.GetBond(mol.GetAtomTag(l[0]), mol.GetAtomTag(l[1]))
            if not bond:
                raise IndexError("Unknown bond: {}-{}".format(l[0], l[1]))
            if l[2] == 1:
                bond.SetOrder(ix.BondOrder.Single)
            elif l[2] == 2:
                bond.SetOrder(ix.BondOrder.Double)
            elif l[2] == 3:
                bond.SetOrder(ix.BondOrder.Triple)
            elif l[2] == 4:
                bond.SetOrder(ix.BondOrder.Quadruple)
            elif l[2] == 5:
                bond.SetOrder(ix.BondOrder.Aromatic)
            elif l[2] == 6:
                bond.SetOrder(ix.BondOrder.OneAndAHalf)
            elif l[2] == 7:
                bond.SetOrder(ix.BondOrder.TwoAndAHalf)
        elif line[0] == "MOLECULE":
            mol.SetMolecularCharge(l[0])

    set_implicits = set(set_implicits)
    for atom in mol.GetAtoms():
        if atom.GetElement() != "C":
            continue
        if atom.GetTag() in set_implicits:
            continue

        bonded_count = 0
        aromatic_bonds = False
        for bond in atom.GetBonds():
            if bond.GetOrder() == ix.BondOrder.Single:
                bonded_count += 1
            elif bond.GetOrder() == ix.BondOrder.Double:
                bonded_count += 2
            elif bond.GetOrder() == ix.BondOrder.Triple:
                bonded_count += 3
            elif bond.GetOrder() == ix.BondOrder.Quadruple:
                bonded_count += 4
            elif bond.GetOrder() == ix.BondOrder.Aromatic:
                if not aromatic_bonds:
                    bonded_count += 1
                    aromatic_bonds = True
                bonded_count += 1
            elif bond.GetOrder() == ix.BondOrder.OneAndAHalf:
                bonded_count += 1.5
            elif bond.GetOrder() == ix.BondOrder.TwoAndAHalf:
                bonded_count += 2.5

        if (((bonded_count - int(bonded_count)) != 0) or bonded_count > 4):
            raise ValueError("Atom tag {} has weird valence state.".format(
                atom.GetTag()))
        atom.SetImplicitCount(4 - bonded_count)

    tot_charge = sum(atm.GetFormalCharge() for atm in mol.GetAtoms())
    if tot_charge != mol.GetMolecularCharge():
        raise ValueError(
            "Sum of atom formal charges does not match molecular charge")
Пример #4
0
def LoadMTBFile(path, ff, details=None):
    file = list(ix.LoadFile(path.expanduser()))

    blocks = [file[0]]
    for i in range(len(file) - 1):
        if file[i] == "END" and len(file[i + 1]):
            blocks.append(file[i + 1])

    mol = ix.Molecule(path.stem)
    bondtype = ix.BondType.Quartic
    angletype = ix.AngleType.CosineHarmonic
    impropertype = ix.DihedralType.Improper
    propertype = ix.DihedralType.Proper
    for b in blocks:
        start = file.index(b) + 1

        if b == "MTBUILDBLSOLUTE":
            counts = [0, 0, 0, 0, 0, 0]
            start_line = [0, 0, 0, 0, 0, 0]
            mol.SetName(file[start])
            for i in range(len(counts)):
                pre = start + 1 + len(counts[:i]) + sum(counts[:i])
                counts[i] = int(file[pre].split()[0])
                start_line[i] = pre + 1

            for i in range(len(file)):
                dat = file[i].split()
                if i in (x - 1 for x in start_line) or i <= start:
                    continue
                elif i < start_line[0] + counts[0]:  # Atom data
                    atom = mol.NewAtom()
                    atom.SetTag(int(dat[0]))
                    atom.SetName(dat[1])
                    atom.SetType(ff.GetAtomType(int(dat[2])))
                    atom.SetPartialCharge(float(dat[4]))
                    atom.SetElement(atom.GetType().GetElement())
                elif i < start_line[1] + counts[1]:  # Bond data
                    bond = mol.NewBond(mol.GetAtomTag(int(dat[0])),
                                       mol.GetAtomTag(int(dat[1])))
                    bond.SetType(ff.GetBondType(bondtype, int(dat[2])))
                elif i < start_line[2] + counts[2]:  # Angle data
                    angle = mol.GetAngle(mol.GetAtomTag(int(dat[0])),
                                         mol.GetAtomTag(int(dat[1])),
                                         mol.GetAtomTag(int(dat[2])))
                    if not angle:
                        raise IndexError(
                            "No angle found: {}-{}-{}".format(*dat[:3]))
                    angle.SetType(ff.GetAngleType(angletype, int(dat[3])))
                elif i < start_line[3] + counts[3]:  # Improper dihedrals
                    a = mol.GetAtomTag(int(dat[0]))
                    b = mol.GetAtomTag(int(dat[1]))
                    c = mol.GetAtomTag(int(dat[2]))
                    d = mol.GetAtomTag(int(dat[3]))
                    if mol.HasDihedral(a, b, c, d):
                        dihedral = mol.GetDihedral(a, b, c, d)
                    else:
                        dihedral = mol.NewDihedral(a, b, c, d)
                    dihedral.AddType(
                        ff.GetDihedralType(impropertype, int(dat[4])))
                elif i < start_line[4] + counts[4]:  # Proper dihedrals
                    a = mol.GetAtomTag(int(dat[0]))
                    b = mol.GetAtomTag(int(dat[1]))
                    c = mol.GetAtomTag(int(dat[2]))
                    d = mol.GetAtomTag(int(dat[3]))
                    dihedral = mol.GetDihedral(a, b, c, d)
                    if not dihedral:
                        raise IndexError(
                            "No dihedral found: {}-{}-{}-{}".format(*dat[:4]))
                    dihedral.AddType(
                        ff.GetDihedralType(propertype, int(dat[4])))

    if details is not None:
        LoadIXDFile(details, mol)

    return mol
Пример #5
0
def LoadIFPFile(path):
    pt = ix.GetPeriodicTable()
    data = list(ix.LoadFile(path.expanduser()))
    blocks = [data[0]]
    for i in range(len(data) - 1):
        if data[i] == 'END':
            blocks.append(data[i + 1])
    ff = ix.Forcefield(ix.FFFamily.GROMOS, path.stem)
    for b in blocks:
        start = data.index(b) + 1
        end = data[start:].index('END') + start
        if b == 'BONDSTRETCHTYPECODE':
            ff.ReserveBondTypes(ix.BondType.Harmonic,
                                int(data[start].split()[0]))
            ff.ReserveBondTypes(ix.BondType.Quartic,
                                int(data[start].split()[0]))
            for line in data[start + 1:end]:
                idx, kq, kh, b0 = map(float, line.split())
                ff.LinkBondTypes(
                    ff.NewBondType(ix.BondType.Harmonic, int(idx), kh, b0),
                    ff.NewBondType(ix.BondType.Quartic, int(idx), kq, b0))
        elif b == 'BONDANGLEBENDTYPECODE':
            ff.ReserveAngleTypes(ix.AngleType.Harmonic,
                                 int(data[start].split()[0]))
            ff.ReserveAngleTypes(ix.AngleType.CosineHarmonic,
                                 int(data[start].split()[0]))
            for line in data[start + 1:end]:
                idx, kch, kh, t0 = map(float, line.split())
                ff.LinkAngleTypes(
                    ff.NewAngleType(ix.AngleType.Harmonic, int(idx), kh, t0),
                    ff.NewAngleType(ix.AngleType.CosineHarmonic, int(idx), kch,
                                    t0))
        elif b == 'IMPDIHEDRALTYPECODE':
            ff.ReserveDihedralTypes(ix.DihedralType.Improper,
                                    int(data[start].split()[0]))
            for line in data[start + 1:end]:
                idx, k, epsilon = map(float, line.split())
                ff.NewDihedralType(ix.DihedralType.Improper, int(idx), k,
                                   epsilon)
        elif b == 'TORSDIHEDRALTYPECODE':
            ff.ReserveDihedralTypes(ix.DihedralType.Proper,
                                    int(data[start].split()[0]))
            for line in data[start + 1:end]:
                idx, k, phase, m = map(float, line.split())
                ff.NewDihedralType(ix.DihedralType.Proper, int(idx), k, phase,
                                   int(m))
        elif b == 'SINGLEATOMLJPAIR':
            num_lines = int((end - start - 1) / int(data[start]))
            atm_count = int(data[start])
            ff.ReserveAtomTypes(atm_count)
            for i in range(atm_count):
                lines = []
                for j in range(num_lines):
                    lines.append(data[start + 1 + j + i * num_lines])
                dat = "   ".join(x for x in lines).split()
                atm_dat = {
                    'int_code': int(dat[0]),
                    'name': dat[1],
                    'c6': float(dat[2])**2,
                    'c12': [
                        float(dat[3])**2,
                        float(dat[4])**2,
                        float(dat[5])**2,
                    ],
                    'c6_1_4': float(dat[6])**2,
                    'c12_1_4': float(dat[7])**2,
                    'interactions': dict(),
                }
                ff.NewAtomType(int(dat[0]), dat[1], pt[dat[1][0]])
    return ff