Exemple #1
0
    def __init__(self, solute, gro, traj, build_monomer, spline=False, npores=4):

        self.npores = npores

        print('Loading trajectory...', end='', flush=True)
        self.t = md.load(traj, top=gro)
        print('Done!')

        self.solute = topology.Solute(solute)
        self.monomer = topology.LC(build_monomer)

        # monomer head group only for testing purposes
        # ref = ['C', 'C1', 'C2', 'C3', 'C4', 'C5']
        # solutes_indices = [a.index for a in self.t.topology.atoms if a.residue.name == solute and a.name in ref]
        # self.nsolute = 400
        # self.solute_vectors = self.direction_vectors()
        # self.com = physical.center_of_mass(self.t.xyz[:, solutes_indices, :], [v for v in self.solute.mass.values()][:6])

        solutes_indices = [a.index for a in self.t.topology.atoms if a.residue.name == solute]
        self.nsolute = len(solutes_indices) // self.solute.natoms
        self.solute_vectors = self.direction_vectors()
        self.com = physical.center_of_mass(self.t.xyz[:, solutes_indices, :], [v for v in self.solute.mass.values()])

        reference_atoms = [a.index for a in self.t.topology.atoms if a.name in self.monomer.pore_defining_atoms and
                           a.residue.name in self.monomer.residues]

        self.pore_centers = physical.avg_pore_loc(4, self.t.xyz[:, reference_atoms, :], self.t.unitcell_vectors)

        self.pore_vectors = self.pore_center_vectors()

        self.costheta = self.angles()

        self.nematic_order_parameter = self.nematic()
Exemple #2
0
    def restrict_to_pore(self, r, dwell_fraction=0.95, tails=False, build_monomer='NAcarb11V.gro', spline=False,
                         buffer=0, npores=4):
        """ Restrict calculations to center of masses (COMs) that primarily stay in the pore OR tail region

        :param r: radius of pore. Anything greater than r from the pore center is considered the tail region
        :param dwell_fraction: Fraction of time spent in region of interest required in order to keep trajectory
        :param tails: if True, then restrict calculations to COMs primarily in the tail region
        :param build_monomer: monomer coordinate file of which liquid crystal membrane is mode
        :param spline: track pore centers with a 3D spline
        :param buffer: Do not count molecules below _buffer_ or above z-box-vector - _buffer_

        :type r: float
        :type tails: bool
        :type build_monomer: str
        :type spline: bool
        :type buffer: float
        """

        # find pore centers
        pore_defining_atoms = topology.LC(build_monomer).pore_defining_atoms
        pore_atoms = [a.index for a in self.t.topology.atoms if a.name in pore_defining_atoms]
        if spline:
            print('Creating pore splines')
            pore_centers = physical.trace_pores(self.t.xyz[:, pore_atoms, :], self.t.unitcell_vectors, 20)
        else:
            pore_centers = physical.avg_pore_loc(npores, self.t.xyz[:, pore_atoms, :], self.t.unitcell_vectors)

        results = 0
        if tails:
            results = 1

        inregion = physical.partition(self.com, pore_centers, r, buffer=buffer,
                                      unitcell=self.t.unitcell_vectors, npores=npores)[results]

        dwell = np.full((self.t.n_frames, self.com.shape[1]), False, dtype=bool)

        for t in range(self.t.n_frames):
            dwell[t, inregion[t]] = True

        fraction_dwelled = np.sum(dwell, axis=0) / self.t.n_frames  # fraction of total time spend in region of interest

        keep = np.where(fraction_dwelled >= dwell_fraction)[0]

        self.com = self.com[:, keep, :]
Exemple #3
0
    def __init__(self,
                 gro,
                 top,
                 monomer,
                 rbounds=[0.3, 1],
                 restraints=False,
                 mpi=False,
                 nproc=4):
        """Add set number of water molecules to the tail region of a given configuration

        :param gro: initial coordinate file to be solvated
        :param top: topology associated with gro
        :param nwater: number of water molecules to add to tails
        :param ref: Names of atoms where water molecules will be placed in proximity to
        :param rbounds: list with min, max (in that order) distance of water molecules from a reference atom (nm)

        :type gro: str
        :type top: str
        :type nwater: int
        :type ref: list
        :type rbounds: list

        """

        self.t = md.load(gro)
        self.coordinates = self.t.xyz[0, :, :]  # initial coordinates
        self.natoms = self.t.n_atoms  # number of atoms in the system
        self.rmin, self.rmax = rbounds
        self.restraints = restraints
        self.mpi = mpi
        self.np = nproc

        self.gmx = "gmx"
        if self.mpi:
            self.gmx = "mpirun -np %s gmx_mpi" % self.np

        # handle mdtraj renaming SOL to HOH
        self.res = []
        self.ids = []
        for a in self.t.topology.atoms:
            if a.residue.name == 'HOH':
                self.res.append('SOL')
                if a.name == 'H1':
                    self.ids.append('HW1')
                elif a.name == 'H2':
                    self.ids.append('HW2')
                elif a.name == 'O':
                    self.ids.append('OW')
            else:
                self.res.append(a.residue.name)
                self.ids.append(a.name)

        self.full_box = self.t.unitcell_vectors  # unitcell vectors
        self.box_gromacs = [
            self.full_box[0, 0, 0], self.full_box[0, 1, 1], self.full_box[0, 2,
                                                                          2],
            self.full_box[0, 0, 1], self.full_box[0, 2, 0], self.full_box[0, 1,
                                                                          0],
            self.full_box[0, 0, 2], self.full_box[0, 1, 2], self.full_box[0, 2,
                                                                          0]
        ]

        self.water = topology.Molecule('HOH').xyz[0, ...]
        self.water_alignment_vector = self.water[0, :] - np.mean(
            self.water,
            axis=0)  # vector around which water molecule can be rotated

        self.topname = top

        with open(self.topname, 'r') as f:
            self.top = []
            for line in f:
                self.top.append(line)

        self.add_water_placeholder()

        self.monomer = topology.LC(monomer)
        self.ref_atoms = [
            a.index for a in self.t.topology.atoms
            if a.name in self.monomer.tail_atoms
        ]  # indices of reference atoms
        self.ref_atom_locations = self.t.xyz[
            0, self.ref_atoms, :]  # coordinates of reference atoms

        self.placement_options = [
            i for i in range(len(self.ref_atoms))
        ]  # list of indices corresponding to atoms in ref_atom_locations

        # need to remove hardcoding. Probably use llclib.topology.Residue
        self.water_ids = ['OW', 'HW1', 'HW2']  # water atom names
        self.water_res = ['SOL', 'SOL', 'SOL']  # water residue name

        write_em_mdp(5)  # 5 step energy minimization
Exemple #4
0
    def __init__(self,
                 gro,
                 traj,
                 residue,
                 monomer,
                 begin=0,
                 end=-1,
                 skip=1,
                 npores=4,
                 atoms=None):
        """ Calculate the radial distribution of residue in a hexagonal phase LLC Membrane

        :param gro: Coordinate file (.gro or .pdb)
        :param traj: Trajectory file (.trr or .xtc)
        :param residue: Name of residue whose rdf will be calculated
        :param monomer: Name of monomer used to build LLC Membrane
        :param begin: First frame index
        :param end: Last frame index
        :param skip: Skip every 'skip' frames
        :param npores: Number of pores
        :param atoms: Calculate RDF of atoms specified here which are a part of residue

        :type gro: str
        :type traj: str
        :type residue: str
        :type monomer: str
        :type begin: int
        :type end: int
        :type skip: int
        :type npores: int
        :type atoms: list
        """

        self.t = md.load(traj, top=gro)[begin:end:skip]
        self.box = self.t.unitcell_vectors
        self.npores = npores

        if residue == 'SOL':  # workaround for mdtraj
            residue = 'HOH'

        self.residue = topology.Residue(residue)
        self.monomer = topology.LC('%s.gro' % monomer)

        if atoms is not None and 'all' not in atoms:
            res = [
                a.index for a in self.t.topology.atoms
                if a.residue.name == residue and a.name in atoms
            ]
            mass = [
                self.residue.mass[v] for v in self.residue.mass.keys()
                if v in atoms
            ]
        else:
            res = [
                a.index for a in self.t.topology.atoms
                if a.residue.name == residue
            ]
            mass = [v for v in self.residue.mass.values()]

        self.com = physical.center_of_mass(self.t.xyz[:, res, :], mass)

        self.r = None
        self.density = None
        self.bootstraps = None
        self.errorbars = None
Exemple #5
0
    def __init__(self,
                 gro,
                 build_monomer,
                 residue,
                 traj=False,
                 begin=0,
                 end=-1,
                 skip=1,
                 npores=4):
        """ Define the system and boundaries for pore and tail region

        :param gro: coordinate file
        :param build_monomer: name of annotated monomer coordinate file
        :param traj: trajectory file
        :param begin: first frame to include
        :param end: last frame to include
        :param skip: skip every n frames
        :param npores: number of pores. Assumes that atoms are number sequentially by pore
        """

        print('Loading trajectory...', flush=True, end='')
        if traj:
            self.t = md.load(traj, top=gro)[begin:end:skip]
        else:
            self.t = md.load(gro)
        print('Done')

        # coordinates and unit cell dimensions
        self.pos = self.t.xyz
        box = self.t.unitcell_vectors
        self.box = [
            box[0, 0, 0], box[0, 1, 1], box[0, 2, 2], box[0, 0, 1],
            box[0, 2, 0], box[0, 1, 0], box[0, 0, 2], box[0, 1, 2], box[0, 2,
                                                                        0]
        ]  # gromacs format

        self.ids = [a.name for a in self.t.topology.atoms]
        self.res = [a.residue.name for a in self.t.topology.atoms]

        self.pore_atoms = topology.LC(build_monomer).pore_defining_atoms
        self.npores = npores
        self.pore_centers = None
        self.pore_water = []
        self.tail_water = []

        if residue == 'SOL':
            for a in self.t.topology.atoms:
                if a.residue.name == 'HOH':  # workaround for mdtraj
                    if a.name == 'O':
                        a.name = 'OW'
                    elif a.name == 'H1':
                        a.name = 'HW1'
                    elif a.name == 'H2':
                        a.name = 'HW2'
            for a in self.t.topology.atoms:
                if a.residue.name == 'HOH':
                    a.residue.name = 'SOL'

        self.residue = topology.Residue(residue)
        self.residue_indices = np.array([
            a.index for a in self.t.topology.atoms if a.residue.name == residue
        ])

        if self.residue_indices.size == 0:
            sys.exit("No residue %s found" % residue)

        residue_atom_names = [
            a.name for a in self.t.topology.atoms if a.residue.name == residue
        ]
        masses = [
            self.residue.mass[x]
            for x in residue_atom_names[:self.residue.natoms]
        ]

        print('Calculating centers of mass...', end='', flush=True)
        self.com = physical.center_of_mass(
            self.pos[:, self.residue_indices, :], masses)
        print('Done!')
Exemple #6
0
def add_dummies(t, residue, dummy_residue, out='dummies.gro', nmon=400):

    """
    TODO: This script can be improved quite a bit, but it is functional for now while I develop xlink.py
    :param t: topology object created from mdtraj
    :return:
    """

    LC = topology.LC('%s.gro' % dummy_residue)

    residues = [a.residue.name for a in t.topology.atoms]

    if 'HOH' in residues:
        for a in t.topology.atoms:
            if a.residue.name == 'HOH':
                if a.name == 'O':
                    a.name = 'OW'
                elif a.name == 'H1':
                    a.name = 'HW1'
                elif a.name == 'H2':
                    a.name = 'HW2'
        for a in t.topology.atoms:  # if you change residue name before changing names, this won't work
            if a.residue.name == 'HOH':
                a.residue.name = 'SOL'
            if a.residue.name == residue:
                a.residue.name = dummy_residue

    nsol = 0
    for i in set(residues):
        if i != residue:
            nsol += residues.count(i)

    natoms = t.n_atoms - nsol

    nmonomers = nmon
    Hd = LC.dummies
    ndummies = len(Hd)

    atomspmon = int(natoms / nmonomers)
    v = t.unitcell_vectors

    with open(out, 'w') as f:

        f.write('This is a .gro file\n')
        f.write('%s\n' % (int((atomspmon + ndummies) * nmonomers) + nsol))

        count = 1
        count2 = 0
        for a in t.topology.atoms:
            if count2 != 0 and count2 % atomspmon == 0 and count < (nmonomers * (atomspmon + ndummies)):
                for j in range(ndummies):
                    f.write('{:5d}{:5s}{:>5s}{:5d}{:8.3f}{:8.3f}{:8.3f}\n'.format(int(count / atomspmon), dummy_residue,
                                                                                  Hd[j], count, 0, 0, 0))
                    count += 1

            f.write('{:5d}{:5s}{:>5s}{:5d}{:8.3f}{:8.3f}{:8.3f}\n'.format(a.residue.index + 1, a.residue.name, a.name,
                                                                    count, t.xyz[0, count2, 0], t.xyz[0, count2, 1],
                                                                    t.xyz[0, count2, 2]))
            count += 1
            count2 += 1

        f.write('{:10f}{:10f}{:10f}{:10f}{:10f}{:10f}{:10f}{:10f}{:10f}\n'.format(v[0, 0, 0], v[0, 1, 1], v[0, 2, 2],
                                                                                  v[0, 0, 1], v[0, 2, 0], v[0, 1, 0],
                                                                                  v[0, 0, 2], v[0, 1, 2], v[0, 2, 0]))