Esempio n. 1
0
    def build_column(self, pore, z, theta, correlation=True, var=0, correlation_length=0, pd=0, random_shift=True):
        """ Place a column at angle theta on xy plane with respect to a pore center

        :param pore: pore number (0 : npores - 1)
        :param z: mean z-positions of monomers in column
        :param theta: angle, with respect to pore center where column should be placed (degrees)
        :param correlation: adjust z positions so there is a correlation length
        :param var: variance in multivariate normal distribution used to make correlated points
        :param correlation_length: length for which correlation between stacked monomers to persist
        :param pd: Angle of wedge created between vertically adjacent monomers. Defined by angle between vectors
        extending from pore center to monomer head groups.
        :param random_shift: if True, randomly shift columns in z-direction by choosing a displacement from a uniform \
        distribution bounded by (0, d), where d is the vertical distance between stacked monomers
        :param seed: random seed if you want to reproduce randomly displaced structures

        :type pore: int
        :type z: np.array
        :type theta: float
        :type correlation: bool
        :type var: float
        :type correlation_length: float
        :type pd: float
        :type random_shift: bool
        """

        if correlation:
            z = z_correlation(z, correlation_length, v=var)
            if random_shift:
                dbwl = z[1] - z[0]  # distance between stacked monomers
                z += np.random.uniform(0, dbwl)

        elif random_shift:
            dbwl = z[1] - z[0]  # distance between stacked monomers
            z += np.random.uniform(0, dbwl)

        displaced_theta = pd

        natoms = self.LC_positions.shape[0]  # number of atoms including ions
        pos = np.copy(self.LC_positions)
        pos[:, 0] += self.pore_radius
        displaced_pos = np.copy(pos)

        pos = transform.rotate_coords_z(pos, theta)
        displaced_pos = transform.rotate_coords_z(displaced_pos, theta + displaced_theta)

        column = np.zeros([z.size * natoms, 3])

        before = np.array([0, 0, 0])
        for l in range(z.size):
            if l % 2 == 0:
                column[l * natoms:(l + 1) * natoms, :] = transform.translate(pos, before, np.array([0, 0, z[l]]))
            else:
                column[l * natoms:(l + 1) * natoms, :] = transform.translate(displaced_pos, before, np.array([0, 0, z[l]]))
            self.names += self.LC_names
            self.all_residues += self.LC_residues

        column = transform.translate(column, before, [self.pore_centers[pore, 0], self.pore_centers[pore, 1], 0])

        self.xyz = np.concatenate((self.xyz, column))
Esempio n. 2
0
    def theta_deviation(self, pd=False):

        ideal_column = np.zeros([self.nlayers, 3])
        starting_position = np.array([self.pore_radius, 0, 0])
        ideal_column[:, :] = starting_position
        if pd:
            ideal_column[1::2, :] = transform.rotate_coords_z(starting_position[np.newaxis, :], 33.9155266) #self.angle / 2)
        ideal_pore = np.zeros([ideal_column.shape[0] * self.ncol, 3])
        ideal_pore[:self.nlayers, :] = ideal_column
        for i in range(1, self.ncol):
            ideal_pore[i * self.nlayers: (i + 1) * self.nlayers, :] = transform.rotate_coords_z(
                ideal_column, i * self.angle)

        # layer based systems
        # ideal_layer = np.zeros([5, 3])
        # ideal_layer[0, :] = [self.pore_radius, 0, 0]
        # for i in range(1, 5):
        #     ideal_layer[i, :] = transform.rotate_coords_z(ideal_layer[np.newaxis, 0, :], i * self.angle)
        #
        # ideal_pore = np.zeros([ideal_layer.shape[0] * self.nlayers, 3])
        # for i in range(self.nlayers):
        #     if pd and i % 2 == 1:
        #         ideal_pore[i * ideal_layer.shape[0]: (i + 1) * ideal_layer.shape[0], :] = transform.rotate_coords_z(
        #                                 ideal_layer, self.angle / 2)
        #     else:
        #         ideal_pore[i * ideal_layer.shape[0]: (i + 1) * ideal_layer.shape[0], :] = ideal_layer

        print('Calculating angles needed to minimize angular deviation')
        #angles = np.zeros([self.t.n_frames, self.npores])
        angles = np.linspace(0, 360, self.nrotations)
        angular_deviations = np.zeros([self.t.n_frames, self.npores, self.ncol * self.nlayers])
        for f in tqdm.tqdm(range(self.t.n_frames)):
            for p in range(self.npores):
                deviations = np.zeros([self.nrotations])
                pos = self.com[f, p * self.ncol * self.nlayers:(p + 1) * self.ncol * self.nlayers, :2]
                center = self.p_centers[:, p, f]
                for i, x in enumerate(angles):
                    deviations[i] = minimize_deviation(ideal_pore, x, pos, center)  # , com, ideal_pore, p_centers)
                ideal = transform.rotate_coords_z(ideal_pore, angles[np.argmin(deviations)])
                angular_deviations[f, p, :] = angular_deviation(pos, center, ideal)

        self.theta_values = angular_deviations
        self.theta_values[np.where(self.theta_values < 3)] += 2 * np.pi
        self.theta_values[np.where(self.theta_values > 3)] -= 2 * np.pi
        self.theta_values -= self.theta_values.mean()

        self.dtheta = np.std(self.theta_values)
Esempio n. 3
0
    def align_with_x(self):
        """ Align vector defined by lineatoms in LC object with x axis """

        v = np.array([
            self.LC_positions[self.lineatoms[0], :2] -
            self.LC_positions[self.lineatoms[1], :2]
        ])
        angle = np.arctan(v[0, 1] / v[0, 0])
        self.LC_positions = transform.rotate_coords_z(self.LC_positions,
                                                      -angle * 180 / np.pi)
Esempio n. 4
0
    def build_column(self,
                     pore,
                     z,
                     theta,
                     correlation=True,
                     var=0,
                     correlation_length=0,
                     pd=0,
                     random_shift=True):
        """ Place a column at angle theta on xy plane with respect to a pore center

        :param pore: pore number (0 : npores - 1)
        :param z: mean z-positions of monomers in column
        :param theta: angle, with respect to pore center where column should be placed
        :param correlation: adjust z positions so there is a correlation length
        :param var: variance in multivariate normal distribution used to make correlated points
        :param correlation_length: length for which correlation between stacked monomers to persist
        :param pd: Specify a nonzero value to make a parallel displaced configuration. The distance here (in nm) will\
         be the distance between the center of masses of two vertically stacked monomers.
        :param random_shift: if True, randomly shift columns in z-direction by choosing a displacement from a uniform \
        distribution bounded by (0, d), where d is the vertical distance between stacked monomers

        :type pore: int
        :type z: np.array
        :type theta: float
        :type correlation: bool
        :type var: float
        :type correlation_length: float
        :type pd: float
        :type random_shift: bool
        """

        if correlation:
            z = z_correlation(z, correlation_length, v=var)
            if random_shift:
                dbwl = z[1] - z[0]  # distance between stacked monomers
                z += np.random.uniform(0, dbwl)
        elif random_shift:
            dbwl = z[1] - z[0]  # distance between stacked monomers
            z += np.random.uniform(0, dbwl)

        displaced_theta = (180 / np.pi) * (2 *
                                           np.arcsin(pd /
                                                     (2 * self.pore_radius)))

        natoms = self.LC_positions.shape[0]  # number of atoms including ions
        pos = np.copy(self.LC_positions)
        pos[:, 0] += self.pore_radius
        displaced_pos = np.copy(pos)

        pos = transform.rotate_coords_z(pos, theta)
        displaced_pos = transform.rotate_coords_z(displaced_pos,
                                                  theta + displaced_theta)

        column = np.zeros([z.size * natoms, 3])

        before = np.array([0, 0, 0])
        for l in range(z.size):
            if l % 2 == 0:
                column[l * natoms:(l + 1) * natoms, :] = transform.translate(
                    pos, before, np.array([0, 0, z[l]]))
            else:
                column[l * natoms:(l + 1) * natoms, :] = transform.translate(
                    displaced_pos, before, np.array([0, 0, z[l]]))
            self.names += self.LC_names
            self.all_residues += self.LC_residues

        column = transform.translate(
            column, before,
            [self.pore_centers[pore, 0], self.pore_centers[pore, 1], 0])

        self.xyz = np.concatenate((self.xyz, column))
Esempio n. 5
0
def minimize_deviation(ideal_pore, angle, com, p_center):

    ideal = transform.rotate_coords_z(ideal_pore, angle)  # rotate pore uniformly by some angle

    return np.linalg.norm(angular_deviation(com, p_center, ideal))  # find deviation between ideal and actual positions