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
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
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)' )
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:
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
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!')