def write_final_pore_configuration(self):

        # only do this if we have converged on the correct number of waters
        water_indices = []

        for i in self.solvated.tail_water[
                0]:  # tail_water indices are given as the center of mass of each water
            water_indices += self.solvated.residue_indices[(
                self.water.natoms * i):self.water.natoms * (i + 1)].tolist()

        keep = np.full(self.solvated.pos.shape[1], True,
                       dtype=bool)  # array of True. Booleans are fast
        keep[water_indices] = False  # set pore indices to False

        # change all 'HOH' to 'SOL' because mdtraj changed it
        res = np.array(self.solvated.res)
        res[np.where(np.array(self.solvated.res) == 'HOH')[0]] = 'SOL'

        file_rw.write_gro_pos(self.solvated.pos[0, keep, :],
                              'solvated_pores.gro',
                              ids=np.array(self.solvated.ids)[keep],
                              res=res[keep],
                              box=self.solvated.box)

        # rewrite topology files
        self.input_files('solvated_pores.gro', 'nvt')
Esempio n. 2
0
def place_water(xyz, water_placement_point, ids, res, box, emsteps, rem):

    water = md.load('%s/../top/solutes/water.gro' %
                    location)  # load water structure
    water_xyz, water_centroid, water_alignment_vector, water_ids, water_res = water_parameters(
        water)

    placed_water_coordinates = solvate_tails.random_water_orientation(
        water_xyz, water_alignment_vector, water_placement_point)
    new_coordinates = np.concatenate((xyz, placed_water_coordinates),
                                     axis=0)  # add to full list of coordinates
    names = ids + water_ids  # add water to ids
    residues = res + water_res  # add water residue to res
    file_rw.write_gro_pos(new_coordinates,
                          'water.gro',
                          ids=names,
                          res=residues,
                          box=box)  # write out config with new water
    energy_minimize(emsteps, nwater + 1, rem,
                    water_placement_point)  # energy minimzed system
    nrg = subprocess.check_output(
        ["awk", "/Potential Energy/ {print $4}",
         "em.log"])  # get Potential energy from em.log

    try:
        return float(nrg.decode("utf-8"))
    except ValueError:
        return 0  # If the system did not energy minimize, the above statement will not work because nrg will be an
Esempio n. 3
0
    def place_solute(self,
                     solute,
                     placement_point,
                     random=False,
                     freeze=False,
                     rem=.5):
        """
        Place solute at desired point and energy minimze the system
        :param solute: name of solute object (str)
        :param placement_point: point to place solute (np.array([3])
        :param random: place solute at random point in box (bool)
        :param freeze: freeze all atoms outside rem during energy minimization (bool)
        :param rem: radius from placement_point within which atoms will NOT be frozen (float, nm)
        :return:
        """

        # randomly rotate the molecule and then tranlate it to the placement point
        solute_positions = transform.random_orientation(
            solute.t.xyz[0, ...],
            solute.t.xyz[0, 0, :] - solute.t.xyz[0, 1, :], placement_point)
        self.positions = np.concatenate(
            (self.positions, solute_positions))  # add to array of positions
        self.residues += solute.res  # add solute residues to list of all residues
        self.names += [
            solute.names.get(i) for i in range(1, solute.natoms + 1)
        ]  # add solute atom names to all names
        self.top.add_residue(solute, write=True)  # add 1 solute to topology

        # write new .gro file
        file_rw.write_gro_pos(self.positions,
                              self.intermediate_fname,
                              box=self.box_gromacs,
                              ids=self.names,
                              res=self.residues)

        if freeze:
            self.freeze_ndx(solute_placement_point=placement_point,
                            res=solute.resname)

        nrg = self.energy_minimize(self.em_steps, freeze=freeze)

        if nrg >= 0:
            self.revert(solute)
            if random:
                self.place_solute_random(solute)
            else:
                #self.remove_water(placement_point, 3)
                self.place_solute(solute, placement_point, freeze=True)
        else:
            p3 = subprocess.Popen(
                ["cp", "em.gro",
                 "%s" % self.intermediate_fname])
            p3.wait()
            self.positions = md.load(
                '%s' %
                self.intermediate_fname).xyz[0, :, :]  # update positions
Esempio n. 4
0
 def write_config(self, name='out.gro'):
     """
     Write .gro coordinate file from current positions
     :param name: name of coordinate file to write (str)
     """
     # write new .gro file
     file_rw.write_gro_pos(self.positions,
                           name,
                           box=self.box_gromacs,
                           ids=self.names,
                           res=self.residues)
Esempio n. 5
0
    def write_gro(self, out, ucell):
        """ Write coordinate file in .gro format

        :param out: name of output .gro file
        :param ucell: unitcell vectors

        :type out: str
        :type ucell: np.ndarray, shape(3,3)

        """

        file_rw.write_gro_pos(self.xyz, out, ids=self.names, res=self.all_residues, ucell=ucell)
Esempio n. 6
0
    def place_solute(self,
                     solute,
                     placement_point,
                     random=False,
                     freeze=False,
                     rem=.5):
        """
        Place solute at desired point and energy minimze the system
        :param solute: name of solute object (str)
        :param placement_point: point to place solute (np.array([3])
        :param random: place solute at random point in box (bool)
        :param freeze: freeze all atoms outside rem during energy minimization (bool)
        :param rem: radius from placement_point within which atoms will NOT be frozen (float, nm)
        :return:
        """

        # p = placement_point - (solute.com - solute.xyz[0, 0, :])  # want to move com to placement point
        #solute_positions = random_orientation(solute.xyz[0, ...], solute.xyz[0, 0, :] - solute.xyz[0, 1, :], placement_point)  # to be fixed in THE FUTURE
        solute_positions = transform.translate(
            solute.xyz[0, :, :], solute.com,
            placement_point)  # translate solute to placement point
        self.positions = np.concatenate(
            (self.positions, solute_positions))  # add to array of positions
        self.residues += solute.residues  # add solute residues to list of all residues
        self.names += solute.names  # add solute atom names to list of all names
        self.top.add_residue(solute, write=True)  # add 1 solute to topology

        # write new .gro file
        file_rw.write_gro_pos(self.positions,
                              self.intermediate_fname,
                              box=self.box_gromacs,
                              ids=self.names,
                              res=self.residues)

        if freeze:
            self.freeze_ndx(solute_placement_point=placement_point,
                            res=solute.resname)

        nrg = self.energy_minimize(self.em_steps, freeze=freeze)

        if nrg >= 0:
            self.revert(solute)
            if random:
                self.place_solute_random(solute)
            else:
                #self.remove_water(placement_point, 3)
                self.place_solute(solute, placement_point, freeze=False)
Esempio n. 7
0
    def place_water(self, nwater, steps):
        """
        Place water molecules near a random reference atom and perform a short energy minimization
        :param placement_options: All of the possible indexes of reference atoms near which a water molecule could be placed (list)
        :param ref_atom_locations: xyz coordinates of reference atoms (numpy array [number of ref atoms, 3]
        :param coordinates: Coordinates of full system (numpy array [natoms, 3])
        :param rmin: minimimum distance to place water molecules from reference atom (float)
        :param rmax: maximum distance to place water molecules from reference atom (float)
        :param ids: all atom names in order they appear in coordinates (list)
        :param res: all residue atoms in order they appear in coordinates (list)
        :param nwater: number of water molecules in the system (int)
        :param steps: number of energy minimization steps to take (int)
        :return: Potential energy of slightly minimized system, coordinates of minimized system, atom used for placement,
        new locations of reference atoms
        """

        placement_atom = np.random.choice(
            self.placement_options
        )  # choose which atom to place water molecule near
        placement = random_pt_spherical_shell(
            self.ref_atom_locations[placement_atom, :], self.rmin,
            self.rmax)  # point near placement atom
        placed_water_coordinates = transform.random_orientation(
            self.water, self.water_alignment_vector, placement)
        new_coordinates = np.concatenate(
            (self.coordinates, placed_water_coordinates),
            axis=0)  # add to full list of coordinates
        names = self.ids + self.water_ids  # add water to ids
        residues = self.res + self.water_res  # add water residue to res
        file_rw.write_gro_pos(
            new_coordinates,
            'water.gro',
            ids=names,
            res=residues,
            box=self.box_gromacs)  # write out config with new water
        minimized_coordinates, new_ref_atom_locations = self.energy_minimize(
            steps, nwater + 1)  # energy minimzed system
        nrg = subprocess.check_output(
            ["awk", "/Potential Energy/ {print $4}",
             "em.log"])  # get Potential energy from em.log

        return float(
            nrg.decode("utf-8")
        ), minimized_coordinates, placement_atom, new_ref_atom_locations
Esempio n. 8
0
    def cleanup(self, out='xlinked.gro', dummy_atom_name='hc_d'):
        """
        Remove virtual sites in .gro and topology.
        :param out: name of output .gro file to be written
        :param dummy_atom_name: atom type of dummy atom
        :return: A .gro file and an .itp topology file without dummy atoms
        """

        keep = [
            i for i, x in enumerate(self.xlink_residue_atoms.type)
            if x != dummy_atom_name
        ]
        keep += [
            a.index for a in self.t.topology.atoms
            if a.residue.name != self.original_residue_name
        ]

        ids = np.array([a.name for a in self.t.topology.atoms],
                       dtype=object)[keep]
        res = np.array([a.residue.name for a in self.t.topology.atoms],
                       dtype=object)[keep]

        # mdtraj workaround because SOL gets renamed to HOH, OW1 to O, HW1 to H1 and HW2 to H2
        for i, x in enumerate(ids):
            if res[i] == 'HOH':
                if x == 'O':
                    ids[i] = 'OW'
                if x == 'H1':
                    ids[i] = 'HW1'
                if x == 'H2':
                    ids[i] = 'HW2'
                res[i] = 'SOL'

        ucell = self.t.unitcell_vectors[-1, ...]

        file_rw.write_gro_pos(self.t.xyz[-1, keep, :],
                              out,
                              ids=ids,
                              res=res,
                              ucell=ucell)

        self.write_assembly_topology(virtual_sites=False,
                                     vsite_atom_name=dummy_atom_name)
Esempio n. 9
0
    def build_spline(self, pore_centers, rep='K'):
        """ Build the spline into the last frame of the trajectory

        :param pore_centers: output of physical.avg_pore_loc() with spline=True
        :param rep: name of atom to use to represent spline

        :return: 'spline.gro'
        """
        pos = self.t.xyz[-1, ...]

        for i in range(4):
            pos = np.concatenate((pos, pore_centers[-1, i, ...]))
        ids = [a.name for a in self.t.topology.atoms]
        res = [a.residue.name for a in self.t.topology.atoms]
        ids += [rep] * pore_centers.shape[2] * pore_centers.shape[1]
        res += [rep] * pore_centers.shape[2] * pore_centers.shape[1]

        file_rw.write_gro_pos(pos,
                              'spline.gro',
                              ucell=self.box[-1, ...],
                              ids=ids,
                              res=res)
Esempio n. 10
0
    def build_com(self, rep='K'):
        """ Build system with COM of residue plotted in order to confirm that this script is working

        :param rep: name of atom to use to represent spline

        :type rep: str

        :return: structure file, 'spline.gro'
        """

        pos = np.concatenate((self.t.xyz[-1, ...], self.com[-1, ...]))

        ids = [a.name for a in self.t.topology.atoms]
        res = [a.residue.name for a in self.t.topology.atoms]
        ids += [rep] * self.com.shape[1]
        res += [rep] * self.com.shape[1]

        file_rw.write_gro_pos(pos,
                              'com.gro',
                              ucell=self.box[-1, ...],
                              ids=ids,
                              res=res)
Esempio n. 11
0
    def insert_all_water(self,
                         nwater,
                         output='solvated.gro',
                         final_topname='topol.top'):

        trials = 0  # number of water placement tries
        # start = time.time()

        for i in tqdm.tqdm(range(nwater), unit='waters'):
            # randomly place water molecule and do short energy minimization
            energy, new_coordinates, placement_atom, new_ref_atom_locations = self.place_water(
                i, 5)
            trials += 1
            count = 0
            while energy > -50000:  # make sure the potential energy doesn't get too close to exploding

                energy, new_coordinates, placement_atom, new_ref_atom_locations = self.place_water(
                    i, 5)
                trials += 1
                count += 1
                if count > 10:
                    # if the energy is too high for water placement, run a longer energy minimization
                    sys.stdout.write(
                        "\r Running longer energy minimization...                                         "
                        "                \r")
                    sys.stdout.flush()
                    file_rw.write_gro_pos(self.coordinates,
                                          'water.gro',
                                          box=self.box_gromacs,
                                          ids=self.ids,
                                          res=self.res)
                    self.coordinates, self.ref_atom_locations = self.energy_minimize(
                        500, i)  # energy minimize and update coordinates
                    count = 0
                    write_em_mdp(1)

            # success_rate = 100*((i + 1) / trials)
            # s = "Waters placed: %s/%s, Placement Success Rate : %3.2f, Potential Energy = %s\r" % (i, nwater,
            #                                                                                        success_rate, energy)
            # sys.stdout.write("\r"+s)
            # sys.stdout.flush()
            self.ids += self.water_ids
            self.res += self.water_res
            self.coordinates = copy.deepcopy(new_coordinates)
            self.placement_options.remove(placement_atom)
            for filename in glob.glob("./#*"):
                os.remove(filename)

        cp = "cp top_intermediate.top %s" % final_topname
        p = subprocess.Popen(cp.split())
        p.wait()

        # energy minimize final configuration until convergence
        write_em_mdp(-1)
        grompp = "%s grompp -f em.mdp -p %s -c water.gro -o %s" % (
            self.gmx, final_topname, output.split('.')[0])
        if self.restraints:
            grompp += " -r water.gro"
        p = subprocess.Popen(grompp.split())
        p.wait()

        mdrun = "%s mdrun -v -deffnm %s" % (self.gmx, output.split('.')[0])
        p = subprocess.Popen(mdrun.split())
        p.wait()
Esempio n. 12
0
    def hexagonal_column_grid(self,
                              npores,
                              ncol_per_pore,
                              r,
                              npoints,
                              frames=1,
                              noise=True,
                              thermal_disorder=[0, 0, 0],
                              shift_range=0):

        self.nframes = frames
        self.locations = np.zeros(
            [self.nframes, npores**2 * npoints * ncol_per_pore, 3])

        xy_pore_centers = np.zeros([npores**2, 2])
        dx = self.box[0] / npores  # distance between pores in x direction

        if r > (dx / 2):
            print(
                'WARNING: The pore radius is such that pores intersect and  columns will be placed outside of the '
                'unit cell which will disrupt periodicity. \nSetting r to %.2f. \nEither change the radius, change '
                'the box dimensions, or change the number of pores in the unit cell.'
                % (dx / 2))

        for i in range(npores):
            row_x = i * self.unit_cell[1, 0] * dx + np.linspace(
                dx / 2, self.box[0] - (dx / 2), npores)
            row_y = i * self.unit_cell[1, 1] * dx + (dx /
                                                     2) * self.unit_cell[1, 1]
            xy_pore_centers[i * npores:(i + 1) * npores, 0] = row_x
            xy_pore_centers[i * npores:(i + 1) * npores, 1] = row_y

        z_separation = self.box[2] / npoints
        column = np.linspace(0, z_separation * (npoints - 1), npoints)

        # For adding noise to quenched disordered configuration
        columns = np.zeros([npores**2 * ncol_per_pore, column.size])
        # radii_noise = np.zeros([npores**2*ncol_per_pore, column.size])
        # theta_noise = np.zeros([npores**2*ncol_per_pore, column.size])
        # #xy_noise = np.zeros([npores**2*ncol_per_pore, column.size, 2])
        # shifts = np.zeros([npores**2*ncol_per_pore])
        # shift_range = 0  # fraction of layer to allow random displacement
        # #thetas = np.random.uniform(0, 2*np.pi, size=npores**2)  # randomly rotate each pore about the z-axis
        # for i in range(npores**2*ncol_per_pore):
        #     #columns[i, :] = z_correlation(column, 10, v=2.074)
        #     columns[i, :] = column + z_separation*np.random.normal(scale=0.322, size=column.size)
        #     radii_noise[i, :] = np.random.normal(loc=r, scale=2.2, size=column.size)
        #     theta_noise[i, :] = np.random.normal(loc=0, scale=.43, size=column.size)
        #     #xy_noise[i, :, :] = np.random.normal(scale=2.3, size=(column.size, 2))
        #     shifts[i] = shift_range * (z_separation / 2) * np.random.uniform(-1, 1)  # shift column by a random amount
        # thetas = np.random.uniform(0, 2*np.pi, size=npores**2)  # randomly rotate each pore about the z-axis

        # for uncorrelated pores
        # shifts = shift_range * (z_separation / 2) * np.random.uniform(-1, 1, size=npores**2)

        print('z-spacing: %.2f' % z_separation)
        print('Pore center spacing: %.2f' % dx)

        for t in range(self.nframes):
            for c in range(npores**2):
                # for each column, choose a random point on the circle with radius, r, centered at the pore center
                # place a column on that point. Equally space remaining columns on circle with reference to that point
                start_theta = np.random.uniform(0, 360) * (np.pi / 180
                                                           )  # random angle

                # For adding noise to quenched disordered configuration
                # start_theta = thetas[c]

                # start_theta = 0
                theta = 2 * np.pi / ncol_per_pore  # angle between columns
                # pore_shift_x = np.random.normal(scale=10)
                # pore_shift_y = np.random.normal(scale=10)
                for a in range(ncol_per_pore):

                    start = ncol_per_pore * c * npoints + a * npoints
                    end = ncol_per_pore * c * npoints + (a + 1) * npoints

                    radii = np.random.normal(loc=r,
                                             scale=thermal_disorder[0],
                                             size=(end - start))
                    theta_col = np.random.normal(loc=(start_theta + a * theta),
                                                 scale=thermal_disorder[1],
                                                 size=(end - start))
                    # For adding noise to quenched disordered configuration
                    # radii = radii_noise[c*ncol_per_pore + a, :]
                    # theta_col = theta_noise[c*ncol_per_pore + a, :] + start_theta + a*theta

                    x = radii * np.cos(theta_col)
                    y = radii * np.sin(theta_col)
                    # x = r*np.cos(start_theta + a*theta)
                    # y = r*np.sin(start_theta + a*theta)

                    self.locations[t, start:end,
                                   0] = xy_pore_centers[c,
                                                        0] + x  #+ pore_shift_x
                    self.locations[t, start:end,
                                   1] = xy_pore_centers[c,
                                                        1] + y  #+ pore_shift_y
                    if noise:
                        shift = shift_range * (
                            z_separation / 2) * np.random.uniform(
                                -1, 1)  # shift column by a random amount
                        #shift = shifts[c]
                    else:
                        shift = 0

                    # x_disorder = r*np.random.normal(scale=thermal_disorder[0], size=(end - start))
                    # y_disorder = r*np.random.normal(scale=thermal_disorder[1], size=(end - start))
                    # z_disorder = z_separation*np.random.normal(scale=thermal_disorder[2], size=(end - start))

                    # disorder = np.vstack((x_disorder, y_disorder, z_disorder)).T

                    self.locations[t, start:end, 2] = z_correlation(
                        column, 10, v=thermal_disorder[2]**2) + shift
                    #self.locations[t, start:end, :2] += np.random.normal(scale=2.3, size=(column.size, 2))
                    #self.locations[t, start:end, 2] = column + shift

                    # for noise about initial configuration
                    #self.locations[t, start:end, 2] = columns[c*ncol_per_pore + a] + shifts[c*ncol_per_pore + a]
                    #self.locations[t, start:end, :2] += xy_noise[c*ncol_per_pore + a, ...]

                    # self.locations[t, start:end, :] += disorder
                    # self.locations[t, start:end, 2] += z_disorder

        from llcsim.llclib import file_rw

        gamma = 2 * np.pi / 3
        a, b, c = self.box
        A = np.array([a / 10, 0, 0])  # vector in x direction
        B = np.array([b / 10 * np.cos(gamma), b / 10 * np.sin(gamma),
                      0])  # vector in y direction
        C = np.array([0, 0, c / 10])

        unitcell_vectors = np.zeros([self.nframes, 3, 3])
        for i in range(frames):
            # vectors don't change but need them as a trajectory
            unitcell_vectors[i, 0, :] = A
            unitcell_vectors[i, 1, :] = B
            unitcell_vectors[i, 2, :] = C

        file_rw.write_gro_pos(self.locations[-1, ...] / 10,
                              'test.gro',
                              ucell=unitcell_vectors[-1, ...])
        traj = md.formats.TRRTrajectoryFile(
            'test.trr', mode='w',
            force_overwrite=True)  # create mdtraj TRR trajectory object
        time = np.linspace(
            0, 1000,
            self.nframes)  # arbitrary times. Times are required by mdtraj
        traj.write(self.locations / 10, time=time,
                   box=unitcell_vectors)  # write the trajectory in .trr format
Esempio n. 13
0
            y = np.linspace(0, L[1], int(bins[1]))  # for converted square box, y box length is same as x
            z = np.linspace(0, L[2], int(bins[2]))

            # redefine bins
            xbin = x[1] - x[0]
            ybin = y[1] - y[0]
            zbin = z[1] - z[0]

            zv = [0.0, 0.0, 0.0]  # zero vector

            # put all atoms inside box - works for single frame and multiframe
            for it in range(locations.shape[0]):  # looped to save memory
                locations[it, ...] = np.where(locations[it, ...] < L, locations[it, ...], locations[it, ...] - L)  # get positions in periodic cell
                locations[it, ...] = np.where(locations[it, ...] > zv, locations[it, ...], locations[it, ...] + L)
            from llcsim.llclib import file_rw
            file_rw.write_gro_pos(center_of_mass[-1, ...], "test1.gro")
            # fourier transform loop
            fft = np.zeros([x.size - 1, y.size - 1, z.size - 1])
            for frame in tqdm.tqdm(range(frames), unit='Frames'):
                H, edges = np.histogramdd(locations[frame, ...], bins=(x, y, z))
                fft += np.abs(np.fft.fftn(H)) ** 2

            fft /= frames  # average of all frames

            # invert the fourier transform back to real space
            fft_inverse = np.fft.ifftn(fft)

            # only works for z slice currently
            centers_x = [edges[0][i] + ((edges[0][i + 1] - edges[0][i]) / 2) for i in range(fft_inverse.shape[0])]
            centers_y = [edges[1][i] + ((edges[1][i + 1] - edges[1][i]) / 2) for i in range(fft_inverse.shape[1])]
            centers_z = np.array([edges[2][i] + ((edges[2][i + 1] - edges[2][i]) / 2) for i in range(fft_inverse.shape[2])])
Esempio n. 14
0
    def __init__(self, gro, res, atoms, bcc=False, name='restrained', com=False, xlink=False,
                 vparams=None):
        """
        :param gro: coordinate file where restraints will be placed
        :param res: name of residue where position restraints are being added
        :param atoms: name of atoms to be restrained in res
        :param bcc: whether or not this system is bicontinuous cubic (affects where topology is found)
        :param name: name of output topology file
        :param com: restrain center of mass of atoms instead of individual atoms
        :param xlink : whether or not the system is in the process of being crosslinked
        :param vparams: A list in the following order : virtual site construction type, atoms to use to build virtual
               site, required length parameters (i.e. a, b, c or d) in the order specified in GROMACS documentation
        """

        t = md.load(gro)

        self.all_coords = t.xyz[0, :, :]  # all coordinates for system
        self.atom_numbers = np.array([a.index + 1 for a in t.topology.atoms if a.name in atoms])
        self.atoms = t.n_atoms  # number of atoms in full system
        self.nmon = len(self.atom_numbers) // len(atoms)  # number of monomer residues
        self.name = name  # name of output files (.itp, .gro if you are using centers of masses)
        self.residue = res  # name of residue to which position restraints are being applied
        self.LC = lc_class.LC('%s.gro' % self.residue)  # everything we can know about the residue
        self.com = com

        # self.keep = np.array([a.index for a in t.topology.atoms if a.name in atoms])  # atoms to keep
        # self.atom_numbers = self.keep + 1  # numbers (not indices) of atoms to keep
        # self.coords = self.all_coords[self.keep, :]  # coordinates of atoms in keep

        if self.com:  # add center of mass virtual site

            # These things are only needed for center of mass virtual site construction
            self.ids = [a.name for a in t.topology.atoms]  # names of all atoms in system
            self.res = [a.residue.name for a in t.topology.atoms]  # residue names of all atoms in system
            self.vparams = vparams
            self.vatoms_numbers = [a.index + 1 for a in t.topology.atoms if a.name in vparams]
            self.box = t.unitcell_vectors[0, :, :]  # box vectors in mdtraj formate
            self.box_gromacs = [self.box[0, 0], self.box[1, 1], self.box[2, 2], self.box[0, 1], self.box[2, 0],
                                self.box[1, 0], self.box[0, 2], self.box[1, 2],
                                self.box[2, 0]]  # gromacs format box vects

            with open('%s/../top/Monomer_Tops/%s.itp' % (location, self.residue), 'r') as f:
                residue_top = []
                for line in f:
                    residue_top.append(line)

            atoms_index = 0
            while residue_top[atoms_index].count('[ atoms ]') == 0:
                atoms_index += 1

            while residue_top[atoms_index] != '\n':
                atoms_index += 1

            residue_top.insert(atoms_index, '{:>6d}{:>5s}{:>6d}{:>6s}{:>6s}{:>5d}{:>13.6f}{:>13.6f}\n'.format(
                self.LC.natoms + 1, 'hc_d', 1, self.LC.residues[0], 'HD', self.LC.natoms + 1, 0, 0))

            if self.vparams[0] == '3fd':
                # 'a' = 0.5 and 'b' = 0.14 (aromatic carbon bond length (nm)) puts a vsite in the middle of benzene
                # if the constructor atoms are 3 non-adjacent carbons from the ring
                residue_top.append('[ virtual_sites3 ]\n')
                residue_top.append('{:<6d}{:<6d}{:<6d}{:<6d}{:<6d}{:<8.4f}{:<8.4f}\n'.format(self.LC.natoms + 1,
                                    self.vatoms_numbers[0], self.vatoms_numbers[1], self.vatoms_numbers[2], 2,
                                    float(self.vparams[-2]), float(self.vparams[-1])))
            else:
                print('Your choice of virtual site has not yet been implemented')
                exit()

            # groups = np.reshape(self.coords, (len(self.keep) // len(atoms), len(atoms), 3))
            # centers_of_mass = np.mean(groups, axis=1)
            # self.coords = centers_of_mass  # redefine coordinates as centers of mass

            file_rw.write_assembly(residue_top, '%s.itp' % self.name, self.nmon, bcc=bcc, xlink=xlink)

            # now the dummies need to be added to the .gro file. They are placed at the end of the residue section
            # This loop works for a single virtual site per monomer. It will need to be modified if multiple sites
            # are to be constructed.
            insert_ndx = self.LC.natoms
            self.atom_numbers = []  # redefine this since everything is renumbered
            for i in range(self.nmon):
                ndx = (i + 1)*insert_ndx + i
                self.ids.insert(ndx, 'HD')
                self.res.insert(ndx, 'HII')  # should make this more general
                self.all_coords = np.insert(self.all_coords, ndx, np.array([0, 0, 0]), axis=0)
                self.atom_numbers.append(ndx + 1)

            file_rw.write_gro_pos(self.all_coords, '%s.gro' % self.name, ids=self.ids, res=self.res, box=self.box_gromacs)
        else:
            file_rw.write_assembly(res, '%s.itp' % self.name, self.nmon, bcc=bcc, xlink=xlink)

        with open('%s.itp' % self.name, 'r') as f:
            self.topology = []
            for line in f:
                self.topology.append(line)
Esempio n. 15
0
                                ld=ld,
                                nlist=nlist)

    else:
        print("Loading saved arrays")
        arrays = np.load('angles_ld_%s.npz' % args.suffix, encoding='bytes')
        angles = arrays['angles']
        centroids = arrays['centroids']
        atoms_per_frame = int(angles.shape[0] / centroids.shape[0])
        angles = angles[args.start * atoms_per_frame:args.end *
                        atoms_per_frame]
        ld = arrays['ld']
        nlist = arrays['nlist']

    if args.write_gro:
        file_rw.write_gro_pos(centroids[-1, :, :], 'centroids.gro', name='NA')

    angles = [value for value in angles if not math.isnan(value)]

    nbins = 45
    (counts, bins) = np.histogram(angles, bins=nbins)
    # plt.hist(angles, bins=nbins)
    # plt.show()

    bin_width = bins[1] - bins[0]
    db = bin_width
    bin_centers = [
        bins[i - 1] + ((bins[i] - bins[i - 1]) / 2)
        for i in range(1, len(bins))
    ]
    integrated_area = np.trapz(