def __init__(self, args, solute='HOH'):
        """

        :param args: arguments fed to argparse
        :param solute: name of solute used to solvate system
        """

        self.args = args

        # get build monomer molecular weight and calculate mw of entire dry system
        self.build_monomer = topology.Residue(args.build_monomer.split('.')[0])
        if self.build_monomer.residues:
            self.build_monomer_mw = sum(
                [x.mw for x in self.build_monomer.residues])
        else:
            self.build_monomer_mw = self.build_monomer.mw

        nmon = args.nopores * args.ncolumns * args.monomers_per_column  # number of build monomers in the system
        self.dry_mass = nmon * self.build_monomer_mw  # mass of dry system

        # calculate required water in pores and tails
        self.water = topology.Residue(solute)
        self.args.weight_percent /= 100.0  # convert to fraction
        self.total_water = int(
            (self.args.weight_percent * nmon * self.build_monomer_mw) /
            (self.water.mw * (1 - self.args.weight_percent)))
        tail_water = self.total_water / (self.args.ratio + 1)
        self.pore_water = int(args.ratio * tail_water)
        self.tail_water = int(tail_water)

        self.r = 0  # pore radius
        self.converged = False
        self.solvated = None  # an object that will describe solvated systems
Esempio n. 2
0
    def __init__(self, gro, traj, residue):
        """ Initialize object to hold description of molecular geometry

        :param gro: name of gro file describing topology of trajectory
        :param traj: gromacs trajectory files (.trr or .xtc)
        :param residue: name of residue to study (as named in .gro file)

        :type gro: str
        :type traj: str
        :type residue: str
        """

        self.residue = topology.Residue(residue)  # make object out of residue

        t = md.load(traj, top=gro)

        self.time = t.time
        self.nframes = t.n_frames  # total frames in simulation

        keep = [
            a.index for a in t.topology.atoms if a.residue.name == residue
        ]  # keep indices of residue of interest

        if len(keep) == 0:
            print(
                "Warning: No atoms selected. Did you pass the correct residue name with the -r flag?"
            )

        self.xyz = t.xyz[:, keep, :]  # xyz coordinates

        self.nres = len(
            keep) // self.residue.natoms  # number of residues in system

        self.res_ndx = np.zeros(
            [self.nres, self.residue.natoms],
            dtype=int)  # organize residue indices by residue
        for r in range(self.nres):
            self.res_ndx[r, :] = np.arange(r * self.residue.natoms,
                                           (r + 1) * self.residue.natoms)

        self.radius = None
        self.volume = None
        self.planarity = None
        self.ellipse_parameters = None
        self.ellipse_uncertainty = None
        self.location = os.path.realpath(
            os.path.join(os.getcwd(),
                         os.path.dirname(__file__)))  # This script location
Esempio n. 3
0
    def narrow_atoms(self, atoms, residue, type, coordination=False):

        if atoms is not None or type is not None:

            if residue is not None:

                if type is not None:
                    # get names of all atoms with the appropriate type
                    atoms = set([
                        a.name for a in self.t.topology.atoms
                        if a.element.symbol == type
                    ])

                # get indices of all atoms in the system that make up the atoms list
                atom_indices = [
                    a.index for a in self.t.topology.atoms
                    if a.residue.name == residue and a.name in atoms
                ]

                if type is not None:
                    # if a residue is specified with an atom type, assume you want the locations of each atom of that
                    # type within each residue.

                    return self.t.xyz[:, atom_indices, :], topology.map_atoms(
                        atom_indices)

                else:
                    # If a residue is specified with atoms, assume that the user wants to isolate calculations to the
                    # center of mass of a group of atoms within a particular residue

                    residue = topology.Residue(residue)
                    atom_mass = [
                        residue.mass[v] for v in residue.mass.keys()
                        if v in atoms
                    ]  # mass of atoms of interest

                    return physical.center_of_mass(self.t.xyz[:, atom_indices, :], atom_mass), \
                           topology.map_atoms(atom_indices, len(atom_mass))

            else:

                if type is not None:
                    # get indices of any atoms whose element = type
                    atom_indices = [
                        a.index for a in self.t.topology.atoms
                        if a.element.symbol == type
                    ]

                else:
                    # get indices of any atoms in the "atoms" list
                    atom_indices = [
                        a.index for a in self.t.topology.atoms
                        if a.name in atoms
                    ]

                return self.t.xyz[:, atom_indices, :], topology.map_atoms(
                    atom_indices)

        else:

            if residue is not None:
                # calculate the center of mass of the residue based on all atoms
                # First get indices of all atoms in the residue
                atom_indices = [
                    a.index for a in self.t.topology.atoms
                    if a.residue.name == residue
                ]
                res = topology.Residue(residue)
                atom_mass = [v for v in res.mass.values()
                             ]  # mass of each atom in an individual residue

                return physical.center_of_mass(self.t.xyz[:, atom_indices, :], atom_mass), \
                       topology.map_atoms(atom_indices, len(atom_mass))

            else:
                # if you forget a flag, exit the program with a descriptive error
                if coordination:
                    sys.exit(
                        'You must supply at least a residue (-cr / --coordinated_residue) or an atom '
                        '(-ca / --coordinated_atoms)')
                else:
                    sys.exit(
                        'You must supply at least a residue (-r / --residue) or an atom name (-a / --atoms)'
                    )
Esempio n. 4
0
                        type=int,
                        help='Desired net charge on molecule')
    parser.add_argument('-p',
                        '--precision',
                        default=6,
                        type=int,
                        help='Number of decimal points')

    return parser


if __name__ == "__main__":

    args = initialize().parse_args()

    res = topology.Residue(args.itp)

    charges = res.charges

    for key, value in charges.items():
        charges[key] = int(value * 10**args.precision)

    net_charge = sum(res.charges.values())

    if net_charge == args.net_charge:
        sys.exit('Charge is already balanced')

    # increment all charge values if net_charge is greater than res.natoms
    n_changes = abs(int(net_charge / res.natoms))

    if net_charge < args.net_charge:
Esempio n. 5
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
Esempio n. 6
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!')