コード例 #1
0
    def calculate_dipoles(self):
        """

        Returns
        -------

        """
        local_indices = np.array([(a.index, a.residue.atom(0).index)
                                  for a in self.structure.top.atoms],
                                 dtype='int32')
        local_displacements = md.compute_displacements(self.structure,
                                                       local_indices,
                                                       periodic=True)

        molecule_indices = np.array([(a.residue.atom(0).index, 0)
                                     for a in self.structure.top.atoms],
                                    dtype='int32')
        molecule_displacements = md.compute_displacements(self.structure,
                                                          molecule_indices,
                                                          periodic=True)

        xyz = local_displacements + molecule_displacements
        conf_dipoles = {}
        for conf in self.conformer_atom_data:
            conf_at_indices = np.asarray(
                [l[0] for l in self.conformer_atom_data[conf]])
            conf_charges = np.asarray(
                [l[1] for l in self.conformer_atom_data[conf]])
            conf_xyz = xyz[0, conf_at_indices, :]
            moments = conf_xyz.transpose(1, 0).dot(conf_charges)
            moments *= 10.0
            conf_dipoles[conf] = moments

        return conf_dipoles
コード例 #2
0
def dipole_moments(traj, charges):
    """Calculate the dipole moments of each frame in a trajectory.

    Parameters
    ----------
    traj : Trajectory
        An mdtraj trajectory.
    charges : np.ndarray, shape=(n_atoms), dtype=float
       Charges of each atom in the trajectory, expressed in units of the
       elementary charge constant.

    Returns
    -------
    moments : np.ndarray, shape=(n_frames, 3), dtype=float
        Dipole moments of trajectory, units of nm * elementary charge.
    
    Notes
    -----
    This code works by first calculating displacements relative to the
    first atom in each residue (e.g. local frame).  Then, this is added
    to the PBC-corrected displacement between the first atom in the two
    molecules.  This total displacement is then used as to calculate the
    box dipole moment.
    """
    local_indices = np.array([(a.index, a.residue.atom(0).index) for a in traj.top.atoms], dtype='int32')
    local_displacements = md.compute_displacements(traj, local_indices, periodic=True)
    
    molecule_indices = np.array([(a.residue.atom(0).index, 0) for a in traj.top.atoms], dtype='int32')
    molecule_displacements = md.compute_displacements(traj, molecule_indices, periodic=True)
    
    xyz = local_displacements + molecule_displacements
    
    moments = xyz.transpose(0, 2, 1).dot(charges)

    return moments
コード例 #3
0
ファイル: project.py プロジェクト: rmatsum836/signac-projects
def dipole_moments_md(traj, charges):
    local_indices = np.array([(a.index, a.residue.atom(0).index) for a in traj.top.atoms], dtype='int32')
    local_displacements = md.compute_displacements(traj, local_indices, periodic=False)

    molecule_indices = np.array([(a.residue.atom(0).index, 0) for a in traj.top.atoms], dtype='int32')
    molecule_displacements = md.compute_displacements(traj, molecule_indices, periodic=False)

    xyz = local_displacements + molecule_displacements

    moments = xyz.transpose(0, 2, 1).dot(charges)

    return moments
コード例 #4
0
def _run_amber_traj(traj, ext_ref):
    # Test triclinic case where simple approach in Tuckerman text does not
    # always work
    distopt = md.compute_distances(traj, [[0, 9999]], opt=True)
    distslw = md.compute_distances(traj, [[0, 9999]], opt=False)
    dispopt = md.compute_displacements(traj, [[0, 9999]], opt=True)
    dispslw = md.compute_displacements(traj, [[0, 9999]], opt=False)

    eq(distopt, distslw, decimal=5)
    eq(dispopt, dispslw, decimal=5)

    assert_allclose(distopt.flatten(), ext_ref, atol=2e-5)

    # Make sure distances from displacements are the same
    eq(np.sqrt((dispopt.squeeze()**2).sum(axis=1)), distopt.squeeze())
    eq(np.sqrt((dispslw.squeeze()**2).sum(axis=1)), distslw.squeeze())
    eq(dispopt, dispslw, decimal=5)
コード例 #5
0
ファイル: test_distance.py プロジェクト: schilli/mdtraj
def _run_amber_traj(trajname, ext_ref):
    # Test triclinic case where simple approach in Tuckerman text does not
    # always work
    traj = md.load(get_fn(trajname), top=get_fn("test.parm7"))
    distopt = md.compute_distances(traj, [[0, 9999]], opt=True)
    distslw = md.compute_distances(traj, [[0, 9999]], opt=False)
    dispopt = md.compute_displacements(traj, [[0, 9999]], opt=True)
    dispslw = md.compute_displacements(traj, [[0, 9999]], opt=False)

    eq(distopt, distslw, decimal=5)
    eq(dispopt, dispslw, decimal=5)

    assert_allclose(distopt.flatten(), ext_ref, atol=2e-5)

    # Make sure distances from displacements are the same
    eq(np.sqrt((dispopt.squeeze() ** 2).sum(axis=1)), distopt.squeeze())
    eq(np.sqrt((dispslw.squeeze() ** 2).sum(axis=1)), distslw.squeeze())
    eq(dispopt, dispslw, decimal=5)
コード例 #6
0
def dipole_moments(traj, charges):
    """Calculate the dipole moments of each frame in a trajectory.

    Parameters
    ----------
    traj : Trajectory
        An mdtraj trajectory.
    charges : np.ndarray, shape=(n_atoms), dtype=float
       Charges of each atom in the trajectory, expressed in units of the
       elementary charge constant.

    Returns
    -------
    moments : np.ndarray, shape=(n_frames, 3), dtype=float
        Dipole moments of trajectory, units of nm * elementary charge.
    
    Notes
    -----
    This code works by first calculating displacements relative to the
    first atom in each residue (e.g. local frame).  Then, this is added
    to the PBC-corrected displacement between the first atom in the two
    molecules.  This total displacement is then used as to calculate the
    box dipole moment.
    """
    local_indices = np.array([(a.index, a.residue.atom(0).index)
                              for a in traj.top.atoms],
                             dtype='int32')
    local_displacements = md.compute_displacements(traj,
                                                   local_indices,
                                                   periodic=True)

    molecule_indices = np.array([(a.residue.atom(0).index, 0)
                                 for a in traj.top.atoms],
                                dtype='int32')
    molecule_displacements = md.compute_displacements(traj,
                                                      molecule_indices,
                                                      periodic=True)

    xyz = local_displacements + molecule_displacements

    moments = xyz.transpose(0, 2, 1).dot(charges)

    return moments
コード例 #7
0
def dangling(frame, dictionary, sign, dist, distOSN, idx, idxOSN, normals):
    pair_ox = np.asarray(list(itertools.product(idx, idxOSN)))
    # remove pairs of same index
    pair_ox = pair_ox[np.std(pair_ox, axis=1) != 0]
    dist_ox = md.compute_distances(frame, pair_ox).reshape(idx.size, -1)
    h1o = np.c_[idx, idx + 1]
    h2o = np.c_[idx, idx + 2]
    # compute H-O vectors
    vec_h1o = md.compute_displacements(frame, h1o).reshape(-1, 3)
    vec_h2o = md.compute_displacements(frame, h2o).reshape(-1, 3)
    cosine_h1o = np.einsum('ij,ij->i', vec_h1o, normals) / np.linalg.norm(
        vec_h1o, axis=1)
    cosine_h2o = np.einsum('ij,ij->i', vec_h2o, normals) / np.linalg.norm(
        vec_h2o, axis=1)
    angle_h1o = np.arccos(np.clip(cosine_h1o, -1, 1)) / np.pi * 180
    angle_h2o = np.arccos(np.clip(cosine_h2o, -1, 1)) / np.pi * 180
    h1ox = np.c_[np.asarray(pair_ox)[:, 0] + 1,
                 np.asarray(pair_ox)[:, 0],
                 np.asarray(pair_ox)[:, 1]]
    h2ox = np.c_[np.asarray(pair_ox)[:, 0] + 2,
                 np.asarray(pair_ox)[:, 0],
                 np.asarray(pair_ox)[:, 1]]
    # compute H-O...O angles
    angle_h1ox = md.compute_angles(frame, h1ox).reshape(idx.size,
                                                        -1) / np.pi * 180
    angle_h2ox = md.compute_angles(frame, h2ox).reshape(idx.size,
                                                        -1) / np.pi * 180
    # selection of dangling OH based on R-beta definition (DOI: 10.1021/acs.jctc.7b00566)
    Rc = dist_ox <= .35
    beta1 = angle_h1ox <= 50
    beta2 = angle_h2ox <= 50
    angles_ho = np.append(angle_h1o[np.sum(beta1 * Rc, axis=1) == 0],
                          angle_h2o[np.sum(beta2 * Rc, axis=1) == 0])
    dictionary['ndang'] = np.append(dictionary['ndang'], angles_ho.size)
    dictionary['all'] = np.append(dictionary['all'], idx.size)
    hist, _ = np.histogram(angles_ho, bins=np.arange(0, 181, 2), density=False)
    dictionary['theta'] += hist
コード例 #8
0
def test_dipole_moments():
    traj = md.load(get_fn("tip3p_300K_1ATM.xtc"), top=get_fn("tip3p_300K_1ATM.pdb"))

    charges = np.tile(tip3p_charges, traj.n_residues)

    moments0 = md.geometry.dipole_moments(traj, charges)

    # Now we screw up the molecule wholeness referencing all distances relative to atom zero.
    atom_indices = np.array([np.zeros(traj.n_atoms), np.arange(traj.n_atoms)], dtype='int32').T  # E.g. [[0, 0], [0, 1], [0, 2], [0, 3]]...
    xyz = md.compute_displacements(traj, atom_indices, periodic=True)  # Define coordinates relative to atom 0, PBC corrected.
    traj.xyz = xyz

    moments1 = md.geometry.dipole_moments(traj, charges)

    eq(moments0, moments1, decimal=4)
コード例 #9
0
def test_static_dielectric():
    traj = md.load(get_fn("tip3p_300K_1ATM.xtc"), top=get_fn("tip3p_300K_1ATM.pdb"))

    charges = np.tile(tip3p_charges, traj.n_residues)

    epsilon0 = md.geometry.static_dielectric(traj, charges, temperature)

    atom_indices = np.array([np.zeros(traj.n_atoms), np.arange(traj.n_atoms)], dtype='int32').T  # E.g. [[0, 0], [0, 1], [0, 2], [0, 3]]...
    xyz = md.compute_displacements(traj, atom_indices, periodic=True)  # Define coordinates relative to atom 0, PBC corrected.
    traj.xyz = xyz
    epsilon1 = md.geometry.static_dielectric(traj, charges, temperature)

    eq(epsilon0, epsilon1, decimal=3)

    reference = 87.1818  # From gromacs, see above comment

    assert abs((epsilon1 - reference) / reference) < 1E-3, "Dielectric tolerance not met!"
コード例 #10
0
def cosine(frame, dist, atom, normals, dictionary, sign, edges, toM, layers):
    selection_string = 'name ' + dictionary['pair'][
        0] + ' or name ' + dictionary['pair'][1]
    pair = np.array(frame.top.select(selection_string)).reshape(-1, 2)
    vec = md.compute_displacements(frame, pair).reshape(-1, 3)
    cosine = np.einsum('ij,ij->i', vec, normals) / np.linalg.norm(vec, axis=1)
    if atom == 'C2':
        cosine = -cosine
    hist, _ = np.histogram(dist, bins=edges, weights=cosine, density=False)
    dictionary['cosine'] += hist * toM
    angle = np.arccos(np.clip(cosine, -1, 1)) / np.pi * 180
    for i in range(len(layers) - 1):
        mask = np.logical_and(dist > layers[i], dist < layers[i + 1])
        hist, _ = np.histogram(angle[mask],
                               bins=np.arange(0, 181, 2),
                               density=False)
        dictionary['theta'][i] += hist
コード例 #11
0
 def calc_solute_solvent_displacements(self, 
                                       traj, 
                                       solute_name, 
                                       solute_center_of_mass, 
                                       solvent_name, 
                                       solvent_center_of_mass,
                                       periodic = True):
     '''
     This function calculates the displacements between solute and solvent center of masses using md.traj's function of displacement. First, the first atoms of the solute and solvent are found. Then, we copy the trajectory, change the coordinates to match center of masses of solute and solvent, then calculate displacements between solute and solvent.
     INPUTS:
         traj: trajectory from md.traj
         solute_name: name of the solute as a string
         solute_center_of_mass: numpy array containing the solute center of mass
         solvent_name: name of the solvent as a string
         solvent_center_of_mass: numpy array containing solvent center of mass
     OUTPUTS:
         displacements: displacements as a time frame x number of displacemeny numpy float           
     '''
     print("--- CALCULATING SOLUTE(%s) and SOLVENT(%s) DISPLACEMENTS"%(solute_name, solvent_name))
     ## COPYING TRAJECTORY
     copied_traj=traj[:]
     
     ## FINDING FIRST ATOM INDEX FOR ALL SOLUTE AND SOLVENT
     Solute_first_atoms = self.find_first_atom_index(traj = traj, residue_name = solute_name )
     Solvent_first_atoms = self.find_first_atom_index(traj = traj, residue_name = solvent_name )
     
     ## CHANGING POSITION OF THE SOLUTE
     copied_traj.xyz[:, Solute_first_atoms] = solute_center_of_mass[:]
     
     if self.map_type == 'COM':
         ## CHANGING POSITIONS OF SOLVENT 
         copied_traj.xyz[:, Solvent_first_atoms] = solvent_center_of_mass[:]        
         ## CREATING ATOM PAIRS BETWEEN SOLUTE AND SOLVENT COM
         atom_pairs = [ [Solute_first_atoms[0], x] for x in Solvent_first_atoms]
     else: ## ALL OTHER OPTIONS
         #self.map_type == 'allatom' or self.map_type == 'allatomwithsoluteoxygen' or self.map_type == '3channel_oxy':
         ## FINDING ALL ATOMS
         num_solvent, solvent_index = calc_tools.find_total_atoms(traj, solvent_name)
         ## CREATING ATOM PAIRS BETWEEN SOLUTE AND EACH SOLVENT
         atom_pairs = [ [Solute_first_atoms[0], x] for x in solvent_index]
         
     ## FINDING THE DISPLACEMENTS USING MD TRAJ -- Periodic is true
     displacements = md.compute_displacements( traj=copied_traj, atom_pairs = atom_pairs, periodic = periodic)
     
     return displacements
コード例 #12
0
def test_dipole_moments(get_fn):
    traj = md.load(get_fn("tip3p_300K_1ATM.xtc"),
                   top=get_fn("tip3p_300K_1ATM.pdb"))

    charges = np.tile(tip3p_charges, traj.n_residues)

    moments0 = md.geometry.dipole_moments(traj, charges)

    # Now we screw up the molecule wholeness referencing all distances relative to atom zero.
    # E.g. [[0, 0], [0, 1], [0, 2], [0, 3]]...
    atom_indices = np.array([np.zeros(traj.n_atoms),
                             np.arange(traj.n_atoms)],
                            dtype='int32').T
    # Define coordinates relative to atom 0, PBC corrected.
    xyz = md.compute_displacements(traj, atom_indices, periodic=True)
    traj.xyz = xyz

    moments1 = md.geometry.dipole_moments(traj, charges)

    eq(moments0, moments1, decimal=4)
コード例 #13
0
def test_static_dielectric(get_fn):
    traj = md.load(get_fn("tip3p_300K_1ATM.xtc"),
                   top=get_fn("tip3p_300K_1ATM.pdb"))

    charges = np.tile(tip3p_charges, traj.n_residues)

    epsilon0 = md.geometry.static_dielectric(traj, charges, temperature)
    # E.g. [[0, 0], [0, 1], [0, 2], [0, 3]]...
    atom_indices = np.array([np.zeros(traj.n_atoms),
                             np.arange(traj.n_atoms)],
                            dtype='int32').T
    # Define coordinates relative to atom 0, PBC corrected.
    xyz = md.compute_displacements(traj, atom_indices, periodic=True)
    traj.xyz = xyz
    epsilon1 = md.geometry.static_dielectric(traj, charges, temperature)

    eq(epsilon0, epsilon1, decimal=3)

    reference = 87.1818  # From gromacs, see above comment

    assert abs((epsilon1 - reference) /
               reference) < 1E-3, "Dielectric tolerance not met!"
コード例 #14
0
ファイル: Wetter.py プロジェクト: slaymuel/mizzle
    def __optimizer(self, coords, centers):
        """Perform the minimization scheme

        Parameters
        ----------
        coords : 3*N array(float)
            Coordinates of all solvate molecules
        centers : array(int)
            Containing all metal centers which has bound solvate in the same
            order as `coords`

        Raises
        ------
        ValueError
            If one or more coordinates are missing centers

        Returns
        -------
        coords
            Optimized oxygen coordinates
        vectors
            Optimized M-O vectors

        """
        self.__numOfOH = len(self.__hydCenters)
        self.__numOfOH2 = len(self.__watCenters)

        vectors = np.empty([0, 3], dtype=float)
        cutoff = 6.0
        M = self.topol.trj.xyz[0][centers] * 10

        if (len(M) != len(coords)):
            raise ValueError("Internal error: some solvate molecules were\
                              not assigned to a center.")

        # Drops duplicates
        centerCoordination = np.array(self.topol.bondgraph.\
                             loc[self.topol.bondgraph['j'].\
                             isin(centers)]['j'].value_counts())
        missing = len(centers) - len(centerCoordination)

        # Readd duplicates
        if (missing > 0):
            centerCoordination = np.append(centerCoordination,\
                                           centerCoordination[\
                                           len(centerCoordination)-missing:])

        centerNeighbours = np.empty([0, 3], dtype=float)
        centerNumNeighbours = np.empty([0], dtype=int)

        # Get neighbours to each center
        self.__verboseprint("Calculating guesses for the optimizer:")
        i = 0
        self.__j = len(centers)
        for center in centers:
            neighbours = md.compute_neighbors(self.topol.trj, cutoff/10.0,\
                                              np.array([center]))

            centerNumNeighbours = np.hstack((centerNumNeighbours,\
                                             len(neighbours[0])))

            centerArray = np.repeat(center, len(neighbours[0]))
            dispArray = np.vstack((neighbours, centerArray))
            dispArray = np.transpose(dispArray)
            dispVectors = md.compute_displacements(self.topol.trj, dispArray,\
                                                   periodic = True)[0]
            neighbourCoords = -dispVectors*10 +\
                              self.topol.trj.xyz[0][center]*10
            centerNeighbours = np.vstack((centerNeighbours, -dispVectors*10 +\
                                          self.topol.trj.xyz[0][center]*10))

            res = minimize(potential.potential, coords[i],
                        args = (np.asarray([center]), self.topol,\
                                np.asarray(np.vstack((neighbourCoords,\
                                np.delete(coords, i, axis=0))), dtype=float),\
                                np.asarray([len(neighbours[0])+\
                                           len(coords)-1]),\
                                self.boxVectors,
                                np.append(self.__dMOH,\
                                                      self.__dMOH2),
                                np.asarray(np.hstack((self.__numOfOH,\
                                                      self.__numOfOH2)))),
                        jac = potential.potential_jac,
                        callback=self.__show_progress_prep,
                        method = self.solver,
                        options=self.prepOptions)
            coords[i] = res.x
            i += 1
            self.__i += 1

        self.__verboseprint("\n")

        self.__i = 0
        self.__centers = centers
        self.__centerNeighbours = centerNeighbours
        self.__centerNumNeighbours = centerNumNeighbours

        # Timings for objective function
        start = timer()
        potential.potential(coords.flatten(), centers, self.topol,\
                            centerNeighbours, centerNumNeighbours,\
                            self.boxVectors,
                                np.append(self.__dMOH,\
                                                      self.__dMOH2),
                                np.asarray(np.hstack((self.__numOfOH,\
                                                      self.__numOfOH2))))
        end = timer()
        self.__potTime = end - start
        self.__verboseprint("Potential takes: " + str(end-start) +\
                          " seconds to calculate")

        start = timer()
        potential.potential_jac(coords.flatten(), centers, self.topol,\
                                centerNeighbours, centerNumNeighbours,\
                                self.boxVectors,
                                np.append(self.__dMOH,\
                                                      self.__dMOH2),
                                np.asarray(np.hstack((self.__numOfOH,\
                                                      self.__numOfOH2))))
        end = timer()
        self.__jacPotTime = end - start
        self.__verboseprint("Potential Jacobian takes: " + str(end-start) +\
              " seconds to calculate\n")

        self.__verboseprint("Minimizing potential with " +\
                          str(len(coords.flatten())) + " free variables...")

        # Run minimization
        self.__start = timer()
        res = minimize(potential.potential, coords,
                        args = (centers, self.topol, centerNeighbours,\
                                centerNumNeighbours, self.boxVectors,
                                np.append(self.__dMOH,\
                                                      self.__dMOH2),
                                np.asarray(np.hstack((self.__numOfOH,\
                                                      self.__numOfOH2)))),
                        jac = potential.potential_jac,
                        method = self.solver,
                        callback = self.__show_progress,
                        options=self.optOptions)

        self.__verboseprint("\n")
        if (res.success):
            if (not self.silent):
                self.__verboseputs.success("Successfully minimized"+\
                                           " potential!\n")
        else:
            self.__verboseputs.warning("Optimization failed... Try with"+\
                                       " different optimizer using the"+\
                                       " -solver flag or increasing max"+\
                                       " iterations with -maxiter\n")

        if (self.optLog):
            file = open('minimization.log', 'w')
            file.write("Iteration:\tFunction value:\n")
            for ind, line in enumerate(self.__optimizationLog):
                file.write(str(ind + 1) + "        \t" + str(line) + "\n")
            print("\n")
            print("Output from Minimizer:")
            file.write(str(res) + "\n")
            file.close()

        coords = np.reshape(res.x, (-1, 3))  # Since minimization returns flat
        # array.

        # Recalculate directional vectors from optimized coordinates
        i = 0
        for coord in coords:
            vectors = np.vstack((vectors, (coord-M[i])/\
                                 np.linalg.norm(coord-M[i])))
            i += 1

        return coords, vectors
コード例 #15
0
def get_pair_displacements(trajectory, topology, substrate_name,
                           substrate_number, atom_types):
    ## IDENTIFY ATOMS
    # Substrate filter
    print('Finding \'interesting\' atoms...')
    print('\t[1]: Not in the substrate')
    print('\t[2]: Not part of the backbone')
    print('\t[3]: Not in water (HOH)')
    print('\t[4]: Are on the list of atom types')
    substrate = [
        atom.index for atom in topology.atoms
        if (atom.residue.name == substrate_name
            and atom.residue.index == substrate_number)
    ]

    # Atoms of interest filter - atom type in list and not part of the backbone
    interesting_atoms = [
        atom.index for atom in topology.atoms
        if (atom.name in atom_types and atom.residue.name != substrate_name
            and not atom.is_backbone and atom.residue.name != 'HOH')
    ]
    print('\t\t\t\t\tSuccess!')
    print('\t# of \'interesting\' atoms:', end=" ")
    print(np.shape(interesting_atoms))

    # Neighbors - selects everyone nearby frame by frame
    print('Finding substrate neighbours...', end=" ")
    substrate_neighbours = md.compute_neighbors(trajectory, 0.5, substrate,
                                                interesting_atoms)
    print('\tSuccess!')

    # Hydrogen atom types
    print('Finding hydrogens...', end=" ")
    h_atom_types = [
        'h1', 'h2', 'h3', 'h4', 'h5', 'ha', 'hc', 'hn', 'ho', 'hp', 'hs', 'HW',
        'hx', 'H', 'h1', 'h2', 'H3', 'h4', 'h5', 'ha', 'HA', 'hc', 'HK', 'hn',
        'ho', 'hp', 'HP', 'hs', 'HT', 'hw', 'HW', 'hx', 'HZ', 'HH3'
    ]
    upper_h_atom_types = [atom_type.upper() for atom_type in h_atom_types]
    print('\t\t\tSuccess!')

    ## CALCULATE
    # Unique neighbors - makes a 1D array of all the unique neighbour atoms from all frames
    print('Eliminating duplicate atoms...', end=" ")
    unique_neighbor_atoms = []
    unique_pairs = []

    for frame in substrate_neighbours:
        for atom in frame:
            if atom not in unique_neighbor_atoms:
                unique_neighbor_atoms.append(atom)

    unique_neighbor_atoms.sort()
    print('\t\tSuccess!')
    print('\t# of unique atoms:', end=" ")
    print(np.shape(unique_neighbor_atoms))

    # Distance between everyone
    print('Combining atoms into pairs...', end=" ")
    pairs = topology.select_pairs(substrate, unique_neighbor_atoms)
    print('\t\tSuccess!')
    print('\t# of atom pairs:', end=" ")
    print(np.shape(pairs))

    print('Eliminating duplicate pairs...', end=" ")
    for pair in pairs:
        atom1 = topology.atom(pair[0])
        atom2 = topology.atom(pair[1])

        # combine atom names - if both names appear in h_bond_types, it's an H-H pair and can be excluded
        atom_name_tuple = [atom1.name.upper(), atom2.name.upper()]
        h_h_pair = all(atom in upper_h_atom_types for atom in atom_name_tuple)

        # filter pairs in the same reside and H-H
        if atom1.residue != atom2.residue and not h_h_pair:
            unique_pairs.append(pair)
    print('\t\tSuccess!')

    # Who's touching?
    print('Selecting pairs with nearby atoms...', end=" ")
    relevant_pairs = []

    for pair in unique_pairs:
        relevant_pair = filter_pair(trajectory, pair, relevant_pairs)

        if relevant_pair is not False:
            relevant_pairs.append(relevant_pair)

    print('\tSuccess!')
    print('\t# of \'relevant\' atom pairs:', end=" ")
    print(np.shape(relevant_pairs))

    # Calculate displacement (vector)
    print('Calculating displacement vectors...', end=" ")
    relevant_displacements = md.compute_displacements(trajectory,
                                                      relevant_pairs)
    print('\tSuccess!')
    print('\tDisplacement array:', end=" ")
    print(np.shape(relevant_displacements))

    return (relevant_displacements)
コード例 #16
0
def calc_dipole(namesolv,
                topology,
                traj,
                bond_definitions,
                forcefield,
                bulk=False,
                mol_pdb=None):
    """
    This script calculates the distribution of molecular dipole moments.
    It calculates distributions both including and omitting polarization.

    Parameters
    ----------
    namesolv: string
        The name of the molecule to calculate the dipole for.
    topology: string
        Filename of the topology file for the entire trajectory.
    traj: string
        Filename of the trajectory.
    bond_definitions:
        Filename of the forcefield residue definitions.
    forcefield:
        Filename of the forcefield definitions.
    bulk:
        Whether to calculate the molecule dipole as an average over all like residues in the bulk.
    mol_pdb:
        If the full system topology contains multiple forcefield files (or is complex for some othe reason),
        it may be easier just to specify a single pdb file for the molecule whose dipole is being calculated.
        In this case, give the full system topology in the usual argument, and give a supplemental pdb filename
        using this argument to calculate charges on the single molecule.

        This is necessary because the force field files are only used for determining charges on the molecule,
        but after charges are determined the forcefield files are no longer used.
    """

    temperature = 300

    # use OpenMM library to get charges
    # here we load pdb without drude oscillators
    if mol_pdb is not None:
        pdb = PDBFile(mol_pdb)
    else:
        pdb = PDBFile(topology)
    pdb.topology.loadBondDefinitions(bond_definitions)
    pdb.topology.createStandardBonds()
    modeller = Modeller(pdb.topology, pdb.positions)

    forcefield = ForceField(forcefield)

    modeller.addExtraParticles(forcefield)
    system = forcefield.createSystem(modeller.topology,
                                     nonbondedCutoff=1.4 * nanometer,
                                     constraints=None,
                                     rigidWater=True)
    nbondedForce = [
        f for f in [system.getForce(i) for i in range(system.getNumForces())]
        if type(f) == NonbondedForce
    ][0]

    # this is not important, this is just to create openmm object that we can use to access topology
    integ_md = DrudeLangevinIntegrator(temperature, 1 / picosecond, 1 * kelvin,
                                       1 / picosecond, 0.001 * picoseconds)
    platform = Platform.getPlatformByName('CPU')
    simmd = Simulation(modeller.topology, system, integ_md, platform)

    #####
    #
    # construct charge array for solvent molecule
    # also construct charge array for static charges,
    # so that we can separately compute static and induced dipole moments
    #
    ####
    charges = []
    chargesnopol = []
    for res in simmd.topology.residues():
        if res.name == namesolv:
            for i in range(len(res._atoms)):
                index = res._atoms[i].index
                (q, sig, eps) = nbondedForce.getParticleParameters(index)
                charges.append(q._value)
                if 'D' in res._atoms[i].name:
                    # no charge on drude without polarization
                    chargesnopol.append(0.0)
                else:
                    # to get non-polarization charges,
                    # look for matching drude particle
                    typeA = res._atoms[i].name
                    typeD = "D" + typeA
                    indexD = -1
                    for j in range(len(res._atoms)):
                        if typeD == res._atoms[j].name:
                            indexD = res._atoms[j].index
                            break
                    if indexD >= 0:
                        (qD, sig,
                         eps) = nbondedForce.getParticleParameters(indexD)
                        qstatic = q._value + qD._value
                    else:
                        qstatic = q._value
                    chargesnopol.append(qstatic)
            break

    systemTopology = mdtraj.load(topology).topology

    # get indices solvent molecules
    solvent = []
    for res in systemTopology.residues:
        if res.name == namesolv:
            solvent.append(list(map(lambda a: a.index, res._atoms)))
            if not bulk:
                break

    center_of_charge_atoms = []
    for res in systemTopology.residues:
        if res.name == namesolv:
            for atom in res._atoms:
                atom_name = {"BF4": "B", "TMA": "N"}[namesolv]

                if atom.name == atom_name:
                    center_of_charge_atoms.append(atom.index)
                    break

            if not bulk:
                break

    # convert from e*nm to Debye
    conv = 1.0 / 0.0208194

    framestart = 0
    frameend = framestart + 1

    muhist = []
    munopolhist = []
    for i in range(framestart, frameend):
        frame = mdtraj.load_frame(traj, i, top=topology)

        # calculate dipole of each solvent molecule
        for j in range(len(solvent)):
            # make a list of all atom pairs with the charge-carrying center
            res_center = center_of_charge_atoms[j]
            atom_pairs = [[res_center, index] for index in solvent[j]]
            disp = compute_displacements(frame, atom_pairs, periodic=True)

            mu = np.array([0.0, 0.0, 0.0])
            munopol = np.array([0.0, 0.0, 0.0])
            for k in range(len(solvent[j])):
                munopol += chargesnopol[k] * disp[0][k]
                mu += charges[k] * disp[0][k]

            muhist.append(la.norm(mu) * conv)
            munopolhist.append(la.norm(munopol) * conv)

    hist1 = np.histogram(muhist, 50, density=True)
    hist2 = np.histogram(munopolhist, 50, density=True)

    print("dipole distribution with polarization")
    for i in range(len(hist1[0])):
        print(hist1[1][i], hist1[0][i])

    print("dipole distribution without polarization")
    for i in range(len(hist2[0])):
        print(hist2[1][i], hist2[0][i])
コード例 #17
0
ファイル: Wetter.py プロジェクト: slaymuel/mizzle
    def __calculate_pair_vectors(self, coordination,\
                               OH_frac, OH2_frac, center):
        """Calculate coordinates for solvate on for 4-coordinated atoms

        Notes
        -----
        Calculates the sum of vectors from oxygen to 4-coordinated metal
        atoms. These vectors are used as first guesses of the positions for
        the hydration molecules.

        Returns
        -------
        vectors : ndarray(float)
            Directional vectors for each solvate
        coord : ndarray(float)
            Coordinates for oxygen atom in each solvate
        centers : ndarray(int)
            List of each center that each solvate belongs to

        """
        centerIndices, neighbourgraph = self.__get_center_neighbours(\
                                            coordination, center)

        if (len(centerIndices) > 0):
            centers = np.empty([0], dtype=int)
            self.__verboseprint(("Found {} centers that are Nmax - 2 = {}-fold"
                               " coordinated\n".format(len(centerIndices),\
                                                      coordination)))

            vectors = np.empty([0, 3], dtype=float)

            randIndices = random.sample(range(0, len(centerIndices)),
                                        int((OH_frac+OH2_frac)*\
                                        float(len(centerIndices))))
            indices = centerIndices[randIndices]

            for center in indices:
                points = np.empty([0, 3], dtype=float)
                tempVectors = np.empty([0, 3], dtype=float)
                pairVectors = np.empty([0, 3], dtype=float)
                sumVec = np.array([0, 0, 0], dtype=float)
                points = np.vstack(
                    (points, self.topol.trj.xyz[0][center] * 10))

                # Get neighbours
                neighbours = np.array(neighbourgraph[center])
                centerArray = np.repeat(center, len(neighbours))

                # Compute displacement vectors
                dispArray = np.vstack((neighbours, centerArray))
                dispArray = np.transpose(dispArray)
                dispVectors = md.compute_displacements(self.topol.trj,\
                                                       dispArray,\
                                                       periodic = True)[0]

                for vector in dispVectors:
                    if (np.linalg.norm(vector) < 0.1):
                        puts.warning("Directional vector less than 0.1,"+\
                              " will not hydrate atom with index: " +\
                              str(center) + ". Please verify structure"+\
                              " before using it.\n")
                        continue
                    vector = vector / np.linalg.norm(vector)
                    tempVectors = np.vstack((tempVectors, vector))
                    sumVec += vector  # Sum M-O vectors

                sumVec = sumVec / np.linalg.norm(sumVec)

                for vector in tempVectors:
                    tempVector = sumVec - vector
                    pairVectors = np.vstack((pairVectors, tempVector))

                #Sort vectors with increasing norm
                pairVectors = sorted(pairVectors,
                                    key = lambda x: np.sqrt(x[0]**2 + x[1]**2\
                                                            + x[2]**2))

                # Choose the two vectors with smallest norm
                pairVec1 = pairVectors[0] / np.linalg.norm(pairVectors[0])
                pairVec2 = pairVectors[1] / np.linalg.norm(pairVectors[1])

                # If there are only 2 neighbours, rotate Pi/2 around
                # directional vector to maximize distance to neighbours
                if (len(tempVectors) == 2):
                    axis = sumVec
                    angle = np.pi / 2
                    pairVec1 = np.dot(mac.rotate_around_vec(axis, angle),\
                                      pairVec1)
                    pairVec2 = np.dot(mac.rotate_around_vec(axis, angle),\
                                      pairVec2)

                # Rotate the vectors towards each other
                # (away from center of bulk)
                crossProd = np.cross(pairVec1, pairVec2)
                dotProdVec1 = np.dot(sumVec, pairVec1)
                dotProdVec2 = np.dot(sumVec, pairVec2)
                if (dotProdVec1 < 0):
                    pairVec1 = np.dot(mac.rotate_around_vec(crossProd,\
                                                            np.pi/7), pairVec1)
                    pairVec2 = np.dot(mac.rotate_around_vec(crossProd,\
                                                           -np.pi/7), pairVec2)
                else:
                    angle = -np.pi / 7
                    pairVec1 = np.dot(mac.rotate_around_vec(crossProd,\
                                                            np.pi/7), pairVec1)
                    pairVec2 = np.dot(mac.rotate_around_vec(crossProd,\
                                                           -np.pi/7), pairVec2)

                vectors = np.vstack((vectors, pairVec1))
                vectors = np.vstack((vectors, pairVec2))
                centers = np.append(centers, center)
                centers = np.append(centers, center)

            return vectors, centers

        else:
            return (np.empty([0, 3], dtype=float), np.empty([0], dtype=int))
コード例 #18
0
ファイル: Wetter.py プロジェクト: slaymuel/mizzle
    def __calculate_vectors(self, coordination,\
                          OH_frac, OH2_frac, center):
        """Calculate coordinates for solvate on for 5-coordinated atoms

            Notes
            -----
            See calculate_pair_vectors

        """
        vectors = np.empty([0, 3], dtype=float)

        vec = np.array([0, 0, 0])
        tempNeighbour = np.array([0, 0, 0])
        #Get indices for metal centers with coordination Nmax - 1
        centerIndices, neighbourgraph = self.__get_center_neighbours(\
                                            coordination, center)

        if (len(centerIndices) > 0):  # If there are any Nmax-1 centers
            centers = np.empty([0], dtype=int)

            self.__verboseprint(("Found {} centers that are Nmax - 1 = {}-fold"
                               " coordinated.\n".format(len(centerIndices),\
                                                       coordination)))

            #Calculate only for user specified fraction
            randIndices = random.sample(range(0, len(centerIndices)),\
                                        int((OH2_frac + OH_frac)*\
                                            float(len(centerIndices))))
            indices = centerIndices[randIndices]

            #Calculate M-O vectors
            for center in indices:
                vec = [0, 0, 0]

                neighbours = np.array(neighbourgraph[center])
                centerArray = np.repeat(center, len(neighbours))
                dispArray = np.vstack((neighbours, centerArray))
                dispArray = np.transpose(dispArray)

                dispVectors = md.compute_displacements(self.topol.trj,\
                                                       dispArray,\
                                                       periodic = True)[0]

                #for neighbour in neighbourgraph[center]:
                for vector in dispVectors:
                    vector = vector / np.linalg.norm(vector)
                    vec = vec + vector

                #If norm of directional vector too small
                if (np.linalg.norm(vec) < 0.1):
                    puts.warning("Directional vector almost 0, will " +\
                          "not hydrate at atom with index: " +\
                           str(center + 1))
                    print("Probably due to symmetric center...\n")

                else:
                    centers = np.append(centers, center)
                    vec = vec / np.linalg.norm(vec)
                    vectors = np.vstack((vectors, vec))

            return vectors, centers

        else:  # Else return empty arrays
            return (np.empty([0, 3], dtype=float), np.empty([0], dtype=int))