Пример #1
0
def angle_distribution(gsd_file,
                       A_name,
                       B_name,
                       C_name,
                       start=0,
                       stop=-1,
                       degrees=False,
                       histogram=False,
                       theta_min=0.0,
                       theta_max=None,
                       normalize=False,
                       bins="auto"):
    """Returns the bond angle distribution for a given triplet of particles 
    
    Parameters
    ----------
    gsdfile : str
        Filename of the GSD trajectory.
    A_name, B_name, C_name : str
        Name(s) of particles that form the angle triplet 
        (found in gsd.hoomd.Snapshot.particles.types)
        They must be given in the same order as they form the angle
    start : int
        Starting frame index for accumulating bond lengths.
        Negative numbers index from the end. (default 0)
    stop : int
        Final frame index for accumulating bond lengths. (default -1)
    degrees : bool, default=False
        If True, the angle values are returned in degrees.
        if False, the angle values are returned in radians.
    histogram : bool, default=False
        If set to True, places the resulting angles into a histogram
        and retrums the histogram's bin centers and heights as 
        opposed to the actual calcualted angles.
    theta_min : float, default = 0.0
        Sets the minimum theta value to be included in the distribution
    theta_max : float, default = None 
        Sets the maximum theta value to be included in the distribution
        If left as None, then theta_max will be either pi radians or
        180 degrees depending on the value set for the degrees parameter
    normalize : bool, default=False
        If set to True, normalizes the angle distribution by the
        sum of the bin heights, so that the distribution adds up to 1. 
    bins : float, int, or str,  default="auto"
        The number of bins to use when finding the distribution
        of bond angles. Using "auto" will set the number of
        bins based on the ideal bin size for the data. 
        See the numpy.histogram docs for more details.

    Returns
    -------
    1-D numpy.array  or 2-D numpy.array
        If histogram is False, Array of actual bond angles in degrees
        If histogram is True, returns a 2D array of bin centers and bin heights.

    """
    if not degrees and theta_max is None:
        theta_max = np.pi
    elif degrees and theta_max is None:
        theta_max = 180

    trajectory = gsd.hoomd.open(gsd_file, mode="rb")
    name = "-".join([A_name, B_name, C_name])
    name_rev = "-".join([C_name, B_name, A_name])

    angles = []
    for snap in trajectory[start:stop]:
        if name not in snap.angles.types and name_rev not in snap.angles.types:
            raise ValueError(f"Angles {name} or {name_rev} not found in "
                             " snap.angles.types. "
                             "A_name, B_name, C_name must match the order "
                             "as they appear in snap.angles.types.")
        for idx, angle_id in enumerate(snap.angles.typeid):
            angle_name = snap.angles.types[angle_id]
            if angle_name == name or angle_name == name_rev:
                pos1 = snap.particles.position[snap.angles.group[idx][0]]
                img1 = snap.particles.image[snap.angles.group[idx][0]]
                pos2 = snap.particles.position[snap.angles.group[idx][1]]
                img2 = snap.particles.image[snap.angles.group[idx][1]]
                pos3 = snap.particles.position[snap.angles.group[idx][2]]
                img3 = snap.particles.image[snap.angles.group[idx][2]]
                pos1_unwrap = pos1 + (img1 * snap.configuration.box[:3])
                pos2_unwrap = pos2 + (img2 * snap.configuration.box[:3])
                pos3_unwrap = pos3 + (img3 * snap.configuration.box[:3])
                u = pos1_unwrap - pos2_unwrap
                v = pos3_unwrap - pos2_unwrap
                angles.append(
                    np.round(angle_between_vectors(u, v, False, degrees), 3))
    trajectory.close()

    if histogram:
        if angles[0] < theta_min or angles[-1] > theta_max:
            warnings.warn("There are bond angles that fall outside of "
                          "your set theta_min and theta_max range. "
                          "You may want to adjust this range to "
                          "include all bond angles.")
        bin_centers, bin_heights = get_histogram(np.array(angles),
                                                 bins=bins,
                                                 x_range=(theta_min,
                                                          theta_max))
        return np.stack((bin_centers, bin_heights)).T
    else:
        return np.array(angles)
Пример #2
0
 def test_histogram_normalize(self):
     sample = np.random.randn(100) * -1
     bin_c, bin_h = get_histogram(sample, normalize=True)
     assert all(bin_h <= 1)
Пример #3
0
def bond_distribution(gsd_file,
                      A_name,
                      B_name,
                      start=0,
                      stop=-1,
                      histogram=False,
                      l_min=0.0,
                      l_max=4.0,
                      normalize=True,
                      bins=100):
    """Returns the bond length distribution for a given bond pair 
    
    Parameters
    ----------
    gsdfile : str
        Filename of the GSD trajectory.
    A_name, B_name : str
        Name(s) of particles that form the bond pair
        (found in gsd.hoomd.Snapshot.particles.types)
    start : int
        Starting frame index for accumulating bond lengths.
        Negative numbers index from the end. (default 0)
    stop : int
        Final frame index for accumulating bond lengths. (default -1)
    histogram : bool, default=False
        If set to True, places the resulting bonds into a histogram
        and retrums the histogram's bin centers and heights as 
        opposed to the actual calcualted bonds.
    l_min : float, default = 0.0
        Sets the minimum bond length to be included in the distribution
    l_max : float, default = 5.0 
        Sets the maximum bond length value to be included in the distribution
    normalize : bool, default=False
        If set to True, normalizes the angle distribution by the
        sum of the bin heights, so that the distribution adds up to 1. 
    bins : float, int, or str,  default="auto"
        The number of bins to use when finding the distribution
        of bond angles. Using "auto" will set the number of
        bins based on the ideal bin size for the data. 
        See the numpy.histogram docs for more details.

    Returns
    -------
    1-D numpy.array  or 2-D numpy.array
        If histogram is False, Array of actual bond angles in degrees
        If histogram is True, returns a 2D array of bin centers and bin heights.

    """
    trajectory = gsd.hoomd.open(gsd_file, mode="rb")
    name = "-".join([A_name, B_name])
    name_rev = "-".join([B_name, A_name])

    bonds = []
    for snap in trajectory[start:stop]:
        if name not in snap.bonds.types and name_rev not in snap.bonds.types:
            raise ValueError(f"Bond types {name} or {name_rev} not found "
                             "snap.bonds.types.")
        for idx, bond in enumerate(snap.bonds.typeid):
            bond_name = snap.bonds.types[bond]
            if bond_name in [name, name_rev]:
                pos1 = snap.particles.position[snap.bonds.group[idx][0]]
                img1 = snap.particles.image[snap.bonds.group[idx][0]]
                pos2 = snap.particles.position[snap.bonds.group[idx][1]]
                img2 = snap.particles.image[snap.bonds.group[idx][1]]
                pos1_unwrap = pos1 + (img1 * snap.configuration.box[:3])
                pos2_unwrap = pos2 + (img2 * snap.configuration.box[:3])
                bonds.append(
                    np.round(np.linalg.norm(pos2_unwrap - pos1_unwrap), 3))
    trajectory.close()

    if histogram:
        if bonds[0] < l_min or bonds[-1] > l_max:
            warnings.warn(
                "There are bond lengths that fall outside of "
                "your set l_min and l_max range. You may want to adjust "
                "this range to include all bond lengths.")
        bin_centers, bin_heights = get_histogram(np.array(bonds),
                                                 bins=bins,
                                                 x_range=(l_min, l_max))
        return np.stack((bin_centers, bin_heights)).T
    else:
        return np.array(bonds)
Пример #4
0
 def test_histogram_bins(self):
     sample = np.random.randn(100)
     bin_c, bin_h = get_histogram(sample, bins=20)
     assert len(bin_c) == len(bin_h) == 20