Exemple #1
0
    def convert_rotor(self, theta=None, phi=None, pivot=None, com=None):
        """Convert the rotor axis spherical angles to the axis alpha notation.

        The pivot will be shifted to the point on the axis closest to the CoM, and the alpha angle set.


        @keyword theta: The polar spherical angle.
        @type theta:    float
        @keyword phi:   The azimuthal spherical angle.
        @type phi:      float
        @keyword pivot: The pivot point on the rotation axis.
        @type pivot:    numpy rank-1 3D array
        @keyword com:   The pivot point on the rotation axis.
        @type com:      numpy rank-1 3D array
        """

        # The axis.
        axis = zeros(3, float64)
        spherical_to_cartesian([1.0, theta, phi], axis)

        # Reset the pivot to the closest point on the line to the CoM (shift the pivot).
        self.PIVOT = closest_point_ax(line_pt=pivot, axis=axis, point=com)

        # The CoM-pivot unit vector (for the shifted pivot).
        piv_com = com - self.PIVOT
        piv_com = piv_com / norm(piv_com)

        # The vector perpendicular to the CoM-pivot vector.
        z_axis = array([0, 0, 1], float64)
        perp_vect = cross(piv_com, z_axis)
        perp_vect = perp_vect / norm(perp_vect)

        # Set the alpha angle (the angle between the perpendicular vector and the axis).
        self.AXIS_ALPHA = vector_angle_normal(perp_vect, axis, piv_com)
Exemple #2
0
    def convert_rotor(self, theta=None, phi=None, pivot=None, com=None):
        """Convert the rotor axis spherical angles to the axis alpha notation.

        The pivot will be shifted to the point on the axis closest to the CoM, and the alpha angle set.


        @keyword theta: The polar spherical angle.
        @type theta:    float
        @keyword phi:   The azimuthal spherical angle.
        @type phi:      float
        @keyword pivot: The pivot point on the rotation axis.
        @type pivot:    numpy rank-1 3D array
        @keyword com:   The pivot point on the rotation axis.
        @type com:      numpy rank-1 3D array
        """

        # The axis.
        axis = zeros(3, float64)
        spherical_to_cartesian([1.0, theta, phi], axis)

        # Reset the pivot to the closest point on the line to the CoM (shift the pivot).
        self.PIVOT = closest_point_ax(line_pt=pivot, axis=axis, point=com)

        # The CoM-pivot unit vector (for the shifted pivot).
        piv_com = com - self.PIVOT
        piv_com = piv_com / norm(piv_com)

        # The vector perpendicular to the CoM-pivot vector.
        z_axis = array([0, 0, 1], float64)
        perp_vect = cross(piv_com, z_axis)
        perp_vect = perp_vect / norm(perp_vect)

        # Set the alpha angle (the angle between the perpendicular vector and the axis).
        self.AXIS_ALPHA = vector_angle_normal(perp_vect, axis, piv_com)
Exemple #3
0
    def test_closest_point_ax4(self):
        """Test the closest_point_ax() function."""

        # Get and check the point.
        pt = closest_point_ax(line_pt=array([-2, -2, 0], float64), axis=array([1, 1, 1], float64), point=array([1, -1, 2], float64))
        self.assertAlmostEqual(pt[0], 0.0)
        self.assertAlmostEqual(pt[1], 0.0)
        self.assertAlmostEqual(pt[2], 2.0)
Exemple #4
0
def shift_pivot(pivot_orig=None, com=None, axis=None):
    """Shift the pivot to the closest point on the rotor axis to the CoM.)"""

    # The closest point.
    pivot_new = closest_point_ax(line_pt=pivot_orig, axis=axis, point=com)

    # Printout.
    print("\n%-20s%s" % ("Original pivot:", pivot_orig))
    print("%-20s%s" % ("New pivot:", pivot_new))

    # Return the shifted pivot.
    return pivot_new
Exemple #5
0
def shift_pivot(pivot_orig=None, com=None, axis=None):
    """Shift the pivot to the closest point on the rotor axis to the CoM.)"""

    # The closest point.
    pivot_new = closest_point_ax(line_pt=pivot_orig, axis=axis, point=com)

    # Printout.
    print("\n%-20s%s" % ("Original pivot:", pivot_orig))
    print("%-20s%s" % ("New pivot:", pivot_new))

    # Return the shifted pivot.
    return pivot_new
Exemple #6
0
# Save the state.
state.save('frame_order_fixed_piv', force=True)

# Optimise the pivot and model, again iterating with increasing precision.
frame_order.pivot(pivot, fix=False)
num_int_pts = [1000, 10000, 50000]
func_tol = [1e-2, 1e-3, 1e-4]
for i in range(len(num_int_pts)):
    frame_order.num_int_pts(num=num_int_pts[i])
    minimise.execute('simplex', func_tol=func_tol[i])

# The distance from the optimised pivot and the rotation axis.
opt_piv = array([cdp.pivot_x, cdp.pivot_y, cdp.pivot_z])
print("\n\nOptimised pivot displacement: %s" % norm(pivot - opt_piv))
pt = closest_point_ax(line_pt=pivot, axis=AXIS, point=opt_piv)
print("Distance from axis: %s\n" % norm(pt - opt_piv))

# Recreate the axis and compare to the original.
opt_axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha, pivot=opt_piv, point=pipe_centre_of_mass(verbosity=0))
print("Original axis:   %s" % AXIS)
print("Optimised axis:  %s" % opt_axis)

# Test Monte Carlo simulations.
frame_order.num_int_pts(num=10000)
monte_carlo.setup(number=5)
monte_carlo.create_data()
monte_carlo.initial_values()
minimise.execute('simplex', func_tol=1e-2)
eliminate()
monte_carlo.error_analysis()
Exemple #7
0
# Save the state.
state.save('frame_order_fixed_piv', force=True)

# Optimise the pivot and model, again iterating with increasing precision.
frame_order.pivot(pivot, fix=False)
num_int_pts = [1000, 10000, 50000]
func_tol = [1e-2, 1e-3, 1e-4]
for i in range(len(num_int_pts)):
    frame_order.num_int_pts(num=num_int_pts[i])
    minimise.execute('simplex', func_tol=func_tol[i])

# The distance from the optimised pivot and the rotation axis.
opt_piv = array([cdp.pivot_x, cdp.pivot_y, cdp.pivot_z])
print("\n\nOptimised pivot displacement: %s" % norm(pivot - opt_piv))
pt = closest_point_ax(line_pt=pivot, axis=AXIS, point=opt_piv)
print("Distance from axis: %s\n" % norm(pt - opt_piv))

# Recreate the axis and compare to the original.
opt_axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha, pivot=opt_piv, point=pipe_centre_of_mass(verbosity=0))
print("Original axis:   %s" % AXIS)
print("Optimised axis:  %s" % opt_axis)

# Test Monte Carlo simulations.
frame_order.num_int_pts(num=10000)
monte_carlo.setup(number=5)
monte_carlo.create_data()
monte_carlo.initial_values()
minimise.execute('simplex', func_tol=1e-2)
eliminate()
monte_carlo.error_analysis()
Exemple #8
0
def rotor_pdb(structure=None, rotor_angle=None, axis=None, axis_pt=True, centre=None, span=2e-9, blade_length=5e-10, model=None, staggered=False):
    """Create a PDB representation of a rotor motional model.

    @keyword structure:     The internal structural object instance to add the rotor to as a molecule.
    @type structure:        lib.structure.internal.object.Internal instance
    @keyword rotor_angle:   The angle of the rotor motion in radian.
    @type rotor_angle:      float
    @keyword axis:          The vector defining the rotor axis.
    @type axis:             numpy rank-1, 3D array
    @keyword axis_pt:       A point lying anywhere on the rotor axis.  This is used to define the position of the axis in 3D space.
    @type axis_pt:          numpy rank-1, 3D array
    @keyword centre:        The central point of the representation.  If this point is not on the rotor axis, then the closest point on the axis will be used for the centre.
    @type centre:           numpy rank-1, 3D array
    @keyword span:          The distance from the central point to the rotor blades (meters).
    @type span:             float
    @keyword blade_length:  The length of the representative rotor blades.
    @type blade_length:     float
    @keyword model:         The structural model number to add the rotor to.  If not supplied, the same rotor structure will be added to all models.
    @type model:            int or None
    @keyword staggered:     A flag which if True will cause the rotor blades to be staggered.  This is used to avoid blade overlap.
    @type staggered:        bool
    """

    # Convert the arguments to numpy arrays, radians and Angstrom.
    axis = array(axis, float64)
    axis_pt = array(axis_pt, float64)
    centre = array(centre, float64)
    span = span * 1e10
    blade_length = blade_length * 1e10

    # Normalise.
    axis_norm = axis / norm(axis)

    # Add a structure (handling up to 3 rotors).
    if structure.has_molecule(name='rotor') and structure.has_molecule(name='rotor2'):
        structure.add_molecule(name='rotor3')
        mol_name = 'rotor3'
    elif structure.has_molecule(name='rotor'):
        structure.add_molecule(name='rotor2')
        mol_name = 'rotor2'
    else:
        structure.add_molecule(name='rotor')
        mol_name = 'rotor'

    # Loop over the models.
    for model in structure.model_loop(model):
        # Alias the single molecule from the single model.
        mol = structure.get_molecule(mol_name, model=model.num)

        # The central point.
        mid_point = closest_point_ax(line_pt=axis_pt, axis=axis, point=centre)
        pos_index = mol.atom_add(pdb_record='HETATM', atom_name='CTR', res_name='AX', res_num=1, pos=mid_point, element='PT')

        # Centre of the propellers.
        prop1 = mid_point + axis_norm * span
        prop1_index = pos_index + 1
        mol.atom_add(pdb_record='HETATM', atom_name='PRP', res_name='PRC', res_num=2, pos=prop1, element='O')
        mol.atom_connect(index1=pos_index, index2=prop1_index)

        # Centre of the propellers.
        prop2 = mid_point - axis_norm * span
        prop2_index = pos_index + 2
        mol.atom_add(pdb_record='HETATM', atom_name='PRP', res_name='PRC', res_num=3, pos=prop2, element='O')
        mol.atom_connect(index1=pos_index, index2=prop2_index)

        # Create the rotor propellers.
        rotor_propellers(mol=mol, rotor_angle=rotor_angle, centre=prop1, axis=axis, blade_length=blade_length, staggered=staggered)
        rotor_propellers(mol=mol, rotor_angle=rotor_angle, centre=prop2, axis=-axis, blade_length=blade_length, staggered=staggered)
Exemple #9
0
def rotor(structure=None,
          rotor_angle=None,
          axis=None,
          axis_pt=True,
          label=None,
          centre=None,
          span=2e-9,
          blade_length=5e-10,
          model_num=None,
          staggered=False,
          half_rotor=False):
    """Create a PDB representation of a rotor motional model.

    @keyword structure:     The internal structural object instance to add the rotor to as a molecule.
    @type structure:        lib.structure.internal.object.Internal instance
    @keyword rotor_angle:   The angle of the rotor motion in radian.
    @type rotor_angle:      float
    @keyword axis:          The vector defining the rotor axis.
    @type axis:             numpy rank-1, 3D array
    @keyword axis_pt:       A point lying anywhere on the rotor axis.  This is used to define the position of the axis in 3D space.
    @type axis_pt:          numpy rank-1, 3D array
    @keyword label:         The optional label for the rotor axis.  If supplied, this cannot be longer than 4 characters due to the PDB format restriction.
    @type label:            str
    @keyword centre:        The central point of the representation.  If this point is not on the rotor axis, then the closest point on the axis will be used for the centre.
    @type centre:           numpy rank-1, 3D array
    @keyword span:          The distance from the central point to the rotor blades (meters).
    @type span:             float
    @keyword blade_length:  The length of the representative rotor blades.
    @type blade_length:     float
    @keyword model_num:     The structural model number to add the rotor to.  If not supplied, the same rotor structure will be added to all models.
    @type model_num:        int or None
    @keyword staggered:     A flag which if True will cause the rotor blades to be staggered.  This is used to avoid blade overlap.
    @type staggered:        bool
    @keyword half_rotor:    A flag which if True will cause only the positive half of the rotor to be created.
    @type half_rotor:       bool
    """

    # Convert the arguments to numpy arrays, radians and Angstrom.
    axis = array(axis, float64)
    axis_pt = array(axis_pt, float64)
    centre = array(centre, float64)
    span = span * 1e10
    blade_length = blade_length * 1e10

    # Normalise.
    axis_norm = axis / norm(axis)

    # Add a structure (handling up to 3 rotors).
    if structure.has_molecule(model_num=model_num,
                              name='rotor') and structure.has_molecule(
                                  model_num=model_num, name='rotor2'):
        structure.add_molecule(model_num=model_num, name='rotor3')
        mol_name = 'rotor3'
    elif structure.has_molecule(model_num=model_num, name='rotor'):
        structure.add_molecule(model_num=model_num, name='rotor2')
        mol_name = 'rotor2'
    else:
        structure.add_molecule(model_num=model_num, name='rotor')
        mol_name = 'rotor'

    # Loop over the models.
    for model in structure.model_loop(model_num):
        # Alias the single molecule from the single model.
        mol = structure.get_molecule(mol_name, model=model.num)

        # The central point.
        mid_point = closest_point_ax(line_pt=axis_pt, axis=axis, point=centre)
        pos_index = mol.atom_add(pdb_record='HETATM',
                                 atom_name='CTR',
                                 res_name='RTX',
                                 res_num=1,
                                 pos=mid_point,
                                 element='PT')

        # Centre of the propellers, positive half.
        prop1 = mid_point + axis_norm * span
        prop1_index = pos_index + 1
        mol.atom_add(pdb_record='HETATM',
                     atom_name='PRP',
                     res_name='RTX',
                     res_num=2,
                     pos=prop1,
                     element='O')
        mol.atom_connect(index1=pos_index, index2=prop1_index)

        # Centre of the propellers, negative half.
        if not half_rotor:
            prop2 = mid_point - axis_norm * span
            prop2_index = pos_index + 2
            mol.atom_add(pdb_record='HETATM',
                         atom_name='PRP',
                         res_name='RTX',
                         res_num=3,
                         pos=prop2,
                         element='O')
            mol.atom_connect(index1=pos_index, index2=prop2_index)

        # Create the rotor propellers.
        rotor_propellers(mol=mol,
                         rotor_angle=rotor_angle,
                         centre=prop1,
                         axis=axis,
                         blade_length=blade_length,
                         staggered=staggered)
        if not half_rotor:
            rotor_propellers(mol=mol,
                             rotor_angle=rotor_angle,
                             centre=prop2,
                             axis=-axis,
                             blade_length=blade_length,
                             staggered=staggered)

        # Add atoms for the labels.
        res_num = mol.res_num[-1] + 1
        label_pos1 = mid_point + axis_norm * (span + 2.0)
        mol.atom_add(pdb_record='HETATM',
                     atom_name=label,
                     res_name='RTL',
                     res_num=res_num,
                     pos=label_pos1,
                     element='H')
        if not half_rotor:
            label_pos2 = mid_point - axis_norm * (span + 2.0)
            mol.atom_add(pdb_record='HETATM',
                         atom_name=label,
                         res_name='RTL',
                         res_num=res_num,
                         pos=label_pos2,
                         element='H')