Exemple #1
0
def add_pivots(structure=None, sims=False):
    """Add the pivots for the current frame order model to the structural object.

    @keyword structure: The internal structural object to add the rotor objects to.
    @type structure:    lib.structure.internal.object.Internal instance
    @keyword sims:      A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:         bool
    """

    # Initialise.
    pivots = []
    mols = []
    atom_names = []
    atom_nums = []

    # Create the molecule.
    mol_name = 'pivots'
    structure.add_molecule(name=mol_name)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i+1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The pivot points.
        pivot1 = generate_pivot(order=1, sim_index=sim_indices[i], pdb_limit=True)
        pivot2 = generate_pivot(order=2, sim_index=sim_indices[i], pdb_limit=True)

        # Add the pivots for the double motion models.
        if cdp.model in [MODEL_DOUBLE_ROTOR]:
            # The 1st pivot.
            mols.append(mol)
            pivots.append(pivot1)
            atom_names.append('Piv1')
            atom_nums.append(1)

            # The 2nd pivot.
            mols.append(mol)
            pivots.append(pivot2)
            atom_names.append('Piv2')
            atom_nums.append(2)

        # Add the pivot for the single motion models.
        else:
            mols.append(mol)
            pivots.append(pivot1)
            atom_names.append('Piv')
            atom_nums.append(1)

    # Loop over the data, adding all pivots.
    for i in range(len(mols)):
        mols[i].atom_add(atom_num=atom_nums[i], atom_name=atom_names[i], res_name='PIV', res_num=1, pos=pivots[i], element='C', pdb_record='HETATM')
Exemple #2
0
def generate_axis_system(sim_index=None):
    """Generate and return the full 3D axis system for the current frame order model.

    @keyword sim_index: The optional MC simulation index to obtain the frame for a given simulation.
    @type sim_index:    None or int
    @return:            The full 3D axis system for the model.
    @rtype:             numpy rank-2, 3D float64 array
    """

    # Initialise.
    axis = zeros(3, float64)
    frame = zeros((3, 3), float64)

    # The 1st pivot point.
    pivot = generate_pivot(order=1, sim_index=sim_index, pdb_limit=True)

    # The CoM of the system.
    com = pipe_centre_of_mass(verbosity=0, missing_error=False)

    # The system for the rotor models.
    if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
        # Generate the axis.
        if sim_index == None:
            axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha, pivot=pivot, point=com)
        else:
            axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha_sim[sim_index], pivot=pivot, point=com)

        # Create a full normalised axis system.
        frame_from_axis(axis, frame)

    # The system for the isotropic cones.
    elif cdp.model in MODEL_LIST_ISO_CONE:
        # Generate the axis.
        if sim_index == None:
            axis = create_rotor_axis_spherical(theta=cdp.axis_theta, phi=cdp.axis_phi)
        else:
            axis = create_rotor_axis_spherical(theta=cdp.axis_theta_sim[sim_index], phi=cdp.axis_phi_sim[sim_index])

        # Create a full normalised axis system.
        frame_from_axis(axis, frame)

    # The system for the pseudo-ellipses and double rotor.
    elif cdp.model in MODEL_LIST_PSEUDO_ELLIPSE + MODEL_LIST_DOUBLE:
        # Generate the eigenframe of the motion.
        if sim_index == None:
            euler_to_R_zyz(cdp.eigen_alpha, cdp.eigen_beta, cdp.eigen_gamma, frame)
        else:
            euler_to_R_zyz(cdp.eigen_alpha_sim[sim_index], cdp.eigen_beta_sim[sim_index], cdp.eigen_gamma_sim[sim_index], frame)

    # Unknown model.
    else:
        raise RelaxFault

    # Return the full eigenframe.
    return frame
Exemple #3
0
def simulate(file="simulation.pdb.bz2",
             dir=None,
             step_size=2.0,
             snapshot=10,
             total=1000,
             model=1,
             force=True):
    """Pseudo-Brownian dynamics simulation of the frame order motions.

    @keyword file:      The PDB file for storing the frame order pseudo-Brownian dynamics simulation.  The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.
    @type file:         str
    @keyword dir:       The directory name to place the file into.
    @type dir:          str or None
    @keyword step_size: The rotation will be of a random direction but with this fixed angle.  The value is in degrees.
    @type step_size:    float
    @keyword snapshot:  The number of steps in the simulation when snapshots will be taken.
    @type snapshot:     int
    @keyword total:     The total number of snapshots to take before stopping the simulation.
    @type total:        int
    @keyword model:     Only one model from an analysed ensemble of structures can be used for the pseudo-Brownian simulation, as the simulation and corresponding PDB file consists of one model per simulation.
    @type model:        int
    @keyword force:     A flag which, if set to True, will overwrite the any pre-existing file.
    @type force:        bool
    """

    # Printout.
    print("Pseudo-Brownian dynamics simulation of the frame order motions.")

    # Checks.
    check_pipe()
    check_model()
    check_domain()
    check_parameters()
    check_pivot()

    # Skip the rigid model.
    if cdp.model == MODEL_RIGID:
        print("Skipping the rigid model.")
        return

    # Open the output file.
    file = open_write_file(file_name=file, dir=dir, force=force)

    # The parameter values.
    values = assemble_param_vector()
    params = {}
    i = 0
    for name in cdp.params:
        params[name] = values[i]
        i += 1

    # The structure.
    structure = deepcopy(cdp.structure)
    if structure.num_models() > 1:
        structure.collapse_ensemble(model_num=model)

    # The pivot points.
    num_states = 1
    if cdp.model == MODEL_DOUBLE_ROTOR:
        num_states = 2
    pivot = zeros((num_states, 3), float64)
    for i in range(num_states):
        pivot[i] = generate_pivot(order=i + 1, pdb_limit=True)

    # Shift to the average position.
    average_position(structure=structure, models=[None])

    # The motional eigenframe.
    frame = generate_axis_system()

    # Create the distribution.
    brownian(file=file,
             model=cdp.model,
             structure=structure,
             parameters=params,
             eigenframe=frame,
             pivot=pivot,
             atom_id=domain_moving(),
             step_size=step_size,
             snapshot=snapshot,
             total=total)

    # Close the file.
    file.close()
Exemple #4
0
def distribute(file="distribution.pdb.bz2",
               dir=None,
               atom_id=None,
               total=1000,
               max_rotations=100000,
               model=1,
               force=True):
    """Create a uniform distribution of structures for the frame order motions.

    @keyword file:          The PDB file for storing the frame order motional distribution.  The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.
    @type file:             str
    @keyword dir:           The directory name to place the file into.
    @type dir:              str or None
    @keyword atom_id:       The atom identification string to allow the distribution to be a subset of all atoms.
    @type atom_id:          None or str
    @keyword total:         The total number of states/model/structures in the distribution.
    @type total:            int
    @keyword max_rotations: The maximum number of rotations to generate the distribution from.  This prevents an execution for an infinite amount of time when a frame order amplitude parameter is close to zero so that the subset of all rotations within the distribution is close to zero.
    @type max_rotations:    int
    @keyword model:         Only one model from an analysed ensemble of structures can be used for the distribution, as the corresponding PDB file consists of one model per state.
    @type model:            int
    @keyword force:         A flag which, if set to True, will overwrite the any pre-existing file.
    @type force:            bool
    """

    # Printout.
    print(
        "Uniform distribution of structures representing the frame order motions."
    )

    # Check the total.
    if total > 9999:
        raise RelaxError(
            "A maximum of 9999 models is allowed in the PDB format.")

    # Checks.
    check_pipe()
    check_model()
    check_domain()
    check_parameters()
    check_pivot()

    # Skip the rigid model.
    if cdp.model == MODEL_RIGID:
        print("Skipping the rigid model.")
        return

    # Open the output file.
    file = open_write_file(file_name=file, dir=dir, force=force)

    # The parameter values.
    values = assemble_param_vector()
    params = {}
    i = 0
    for name in cdp.params:
        params[name] = values[i]
        i += 1

    # The structure.
    structure = deepcopy(cdp.structure)
    if structure.num_models() > 1:
        structure.collapse_ensemble(model_num=model)

    # The pivot points.
    num_states = 1
    if cdp.model == MODEL_DOUBLE_ROTOR:
        num_states = 2
    pivot = zeros((num_states, 3), float64)
    for i in range(num_states):
        pivot[i] = generate_pivot(order=i + 1, pdb_limit=True)

    # Shift to the average position.
    average_position(structure=structure, models=[None])

    # The motional eigenframe.
    frame = generate_axis_system()

    # Only work with a subset.
    if atom_id:
        # The inverted selection.
        selection = structure.selection(atom_id=atom_id, inv=True)

        # Delete the data.
        structure.delete(selection=selection, verbosity=0)

    # Create the distribution.
    uniform_distribution(file=file,
                         model=cdp.model,
                         structure=structure,
                         parameters=params,
                         eigenframe=frame,
                         pivot=pivot,
                         atom_id=domain_moving(),
                         total=total,
                         max_rotations=max_rotations)

    # Close the file.
    file.close()
Exemple #5
0
def decompose(root="decomposed", dir=None, atom_id=None, model=1, force=True):
    """Structural representation of the individual frame order motional components.

    @keyword root:          The file root for the PDB files created.  Each motional component will be represented by a different PDB file appended with '_mode1.pdb', '_mode2.pdb', '_mode3.pdb', etc.
    @type root:             str
    @keyword dir:           The directory name to place the file into.
    @type dir:              str or None
    @keyword atom_id:       The atom identification string to allow the decomposition to be applied to subset of all atoms.
    @type atom_id:          None or str
    @keyword model:         Only one model from an analysed ensemble of structures can be used for the decomposition, as the corresponding PDB file consists of one model per state.
    @type model:            int
    @keyword force:         A flag which, if set to True, will overwrite the any pre-existing file.
    @type force:            bool
    """

    # Printout.
    print(
        "PDB representation of the individual components of the frame order motions."
    )

    # Checks.
    check_pipe()
    check_model()
    check_domain()
    check_parameters()
    check_pivot()

    # Skip any unsupported models.
    unsupported = [MODEL_RIGID, MODEL_DOUBLE_ROTOR]
    if cdp.model in unsupported:
        print("Skipping the unsupported '%s' model." % cdp.model)
        return

    # Initialise the angle vector (cone opening angle 1, cone opening angle 2, torsion angle).
    angles = zeros(3, float64)

    # Cone opening.
    if cdp.model in MODEL_LIST_ISO_CONE:
        angles[0] = angles[1] = cdp.cone_theta
    elif cdp.model in MODEL_LIST_PSEUDO_ELLIPSE:
        angles[0] = cdp.cone_theta_y
        angles[1] = cdp.cone_theta_x

    # Non-zero torsion angle.
    if cdp.model in MODEL_LIST_FREE_ROTORS:
        angles[2] = pi
    elif cdp.model in MODEL_LIST_RESTRICTED_TORSION:
        angles[2] = cdp.cone_sigma_max

    # The motional eigenframe.
    frame = generate_axis_system()

    # Mode ordering from largest to smallest.
    indices = argsort(angles)
    angles = angles[indices[::-1]]
    frame = transpose(transpose(frame)[indices[::-1]])

    # The pivot point.
    pivot = generate_pivot(order=1, pdb_limit=True)

    # Loop over each mode.
    for i in range(3):
        # Skip modes with no motion.
        if angles[i] < 1e-7:
            continue

        # Open the output file.
        file_name = "%s_mode%i.pdb" % (root, i + 1)
        file = open_write_file(file_name=file_name, dir=dir, force=force)

        # The structure.
        structure = deepcopy(cdp.structure)
        if structure.num_models() > 1:
            structure.collapse_ensemble(model_num=model)

        # Shift to the average position.
        average_position(structure=structure, models=[None])

        # Create the representation.
        mode_distribution(file=file,
                          structure=structure,
                          axis=frame[:, i],
                          angle=angles[i],
                          pivot=pivot,
                          atom_id=domain_moving())

        # Close the file.
        file.close()
Exemple #6
0
def add_axes(structure=None, representation=None, size=None, sims=False):
    """Add the axis system for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None or 'A', the standard representation will be created.  If set to 'B', the axis system will be inverted.
    @type representation:       None or str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation rotors to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # Create the molecule.
    mol_name = 'axes'
    structure.add_molecule(name=mol_name)

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i+1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The pivot points.
        pivot1 = generate_pivot(order=1, sim_index=sim_indices[i], pdb_limit=True)
        pivot2 = generate_pivot(order=2, sim_index=sim_indices[i], pdb_limit=True)

        # A single z-axis, when no rotor object is present.
        if cdp.model in [MODEL_ISO_CONE_TORSIONLESS]:
            # Print out.
            print("\nGenerating the z-axis system.")

            # The axis.
            if sims:
                axis = create_rotor_axis_spherical(theta=cdp.axis_theta_sim[sim_indices[i]], phi=cdp.axis_phi_sim[sim_indices[i]])
            else:
                axis = create_rotor_axis_spherical(theta=cdp.axis_theta, phi=cdp.axis_phi)
            print(("Central axis: %s." % axis))

            # Transform the central axis.
            axis = dot(T, axis)

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            res_num = generate_vector_residues(mol=mol, vector=axis, atom_name='z-ax', res_name_vect='AXE', res_num=2, origin=pivot1, scale=size)

        # The z-axis connecting two motional modes.
        elif cdp.model in [MODEL_DOUBLE_ROTOR]:
            # Printout.
            print("\nGenerating the z-axis linking the two pivot points.")

            # The axis.
            axis = pivot1 - pivot2
            print(("Interconnecting axis: %s." % axis))

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            res_num = generate_vector_residues(mol=mol, vector=axis, atom_name='z-ax', res_name_vect='AXE', res_num=1, origin=pivot2)

        # The full axis system.
        elif cdp.model in MODEL_LIST_PSEUDO_ELLIPSE:
            # Print out.
            print("\nGenerating the full axis system.")

            # Add the pivot point.
            mol.atom_add(atom_num=1, atom_name='R', res_name='AXE', res_num=1, pos=pivot1, element='C', pdb_record='HETATM')

            # The axis system.
            axes = generate_axis_system(sim_index=sim_indices[i])

            # Rotations and inversions.
            axes = dot(T, axes)

            # The axes to create.
            label = ['x', 'y']
            if cdp.model in [MODEL_PSEUDO_ELLIPSE_TORSIONLESS]:
                label = ['x', 'y', 'z']

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            for j in range(len(label)):
                res_num = generate_vector_residues(mol=mol, vector=axes[:, j], atom_name='%s-ax'%label[j], res_name_vect='AXE', res_num=2, origin=pivot1, scale=size)
Exemple #7
0
def add_rotors(structure=None, representation=None, size=None, sims=False):
    """Add all rotor objects for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None, the rotor will be dumbbell shaped with propellers at both ends.  If set to 'A' or 'B', only half of the rotor will be shown.
    @type representation:       None or str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation rotors to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # Initialise the list structures for the rotor data.
    axis = []
    span = []
    staggered = []
    pivot = []
    rotor_angle = []
    com = []
    label = []
    models = []

    # The half-rotor flag.
    half_rotor = True
    if representation == None:
        half_rotor = False

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i+1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # The pivot points.
        pivot1 = generate_pivot(order=1, sim_index=sim_indices[i], pdb_limit=True)
        pivot2 = generate_pivot(order=2, sim_index=sim_indices[i], pdb_limit=True)

        # The single rotor models.
        if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR, MODEL_ISO_CONE, MODEL_ISO_CONE_FREE_ROTOR, MODEL_PSEUDO_ELLIPSE, MODEL_PSEUDO_ELLIPSE_FREE_ROTOR]:
            # The rotor angle.
            if cdp.model in MODEL_LIST_FREE_ROTORS:
                rotor_angle.append(pi)
            else:
                if sims:
                    rotor_angle.append(cdp.cone_sigma_max_sim[sim_indices[i]])
                else:
                    rotor_angle.append(cdp.cone_sigma_max)

            # Get the CoM of the entire molecule to use as the centre of the rotor.
            if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
                com.append(pipe_centre_of_mass(verbosity=0, missing_error=False))
            else:
                com.append(pivot1)

            # Generate the rotor axis.
            axes = generate_axis_system(sim_index=sim_indices[i])
            axis.append(axes[:, 2])

            # The size of the rotor (Angstrom), taking the cone representation into account by adding 5 Angstrom.
            if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
                span.append(size)
            else:
                span.append(size + 5.0)

            # Stagger the propeller blades.
            if cdp.model in MODEL_LIST_FREE_ROTORS:
                staggered.append(False)
            else:
                staggered.append(True)

            # The pivot.
            pivot.append(pivot1)

            # The label.
            label.append('z-ax')

            # The models.
            if sims:
                models.append(model_nums[i])
            else:
                models.append(None)

        # The double rotor models.
        elif cdp.model in [MODEL_DOUBLE_ROTOR]:
            # Add both rotor angles (the 2nd must come first).
            if sims:
                rotor_angle.append(cdp.cone_sigma_max_2_sim[sim_indices[i]])
                rotor_angle.append(cdp.cone_sigma_max_sim[sim_indices[i]])
            else:
                rotor_angle.append(cdp.cone_sigma_max_2)
                rotor_angle.append(cdp.cone_sigma_max)

            # Set the com to the pivot points.
            com.append(pivot2)
            com.append(pivot1)

            # Generate the eigenframe of the motion.
            frame = generate_axis_system(sim_index=sim_indices[i])

            # Add the x and y axes.
            axis.append(frame[:, 0])
            axis.append(frame[:, 1])

            # The rotor size (Angstrom).
            span.append(size)
            span.append(size)

            # Stagger the propeller blades.
            staggered.append(True)
            staggered.append(True)

            # The pivot points.
            pivot.append(pivot2)
            pivot.append(pivot1)

            # The labels.
            label.append('x-ax')
            label.append('y-ax')

            # The models.
            if sims:
                models.append(model_nums[i])
                models.append(model_nums[i])
            else:
                models.append(None)
                models.append(None)

    # Add each rotor to the structure as a new molecule.
    for i in range(len(axis)):
        rotor(structure=structure, rotor_angle=rotor_angle[i], axis=dot(T, axis[i]), axis_pt=pivot[i], label=label[i], centre=com[i], span=span[i]/1e10, blade_length=5e-10, model_num=models[i], staggered=staggered[i], half_rotor=half_rotor)
Exemple #8
0
def add_pivots(structure=None, sims=False):
    """Add the pivots for the current frame order model to the structural object.

    @keyword structure: The internal structural object to add the rotor objects to.
    @type structure:    lib.structure.internal.object.Internal instance
    @keyword sims:      A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:         bool
    """

    # Initialise.
    pivots = []
    mols = []
    atom_names = []
    atom_nums = []

    # Create the molecule.
    mol_name = 'pivots'
    structure.add_molecule(name=mol_name)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i + 1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The pivot points.
        pivot1 = generate_pivot(order=1,
                                sim_index=sim_indices[i],
                                pdb_limit=True)
        pivot2 = generate_pivot(order=2,
                                sim_index=sim_indices[i],
                                pdb_limit=True)

        # Add the pivots for the double motion models.
        if cdp.model in [MODEL_DOUBLE_ROTOR]:
            # The 1st pivot.
            mols.append(mol)
            pivots.append(pivot1)
            atom_names.append('Piv1')
            atom_nums.append(1)

            # The 2nd pivot.
            mols.append(mol)
            pivots.append(pivot2)
            atom_names.append('Piv2')
            atom_nums.append(2)

        # Add the pivot for the single motion models.
        else:
            mols.append(mol)
            pivots.append(pivot1)
            atom_names.append('Piv')
            atom_nums.append(1)

    # Loop over the data, adding all pivots.
    for i in range(len(mols)):
        mols[i].atom_add(atom_num=atom_nums[i],
                         atom_name=atom_names[i],
                         res_name='PIV',
                         res_num=1,
                         pos=pivots[i],
                         element='C',
                         pdb_record='HETATM')
Exemple #9
0
def generate_axis_system(sim_index=None):
    """Generate and return the full 3D axis system for the current frame order model.

    @keyword sim_index: The optional MC simulation index to obtain the frame for a given simulation.
    @type sim_index:    None or int
    @return:            The full 3D axis system for the model.
    @rtype:             numpy rank-2, 3D float64 array
    """

    # Initialise.
    axis = zeros(3, float64)
    frame = zeros((3, 3), float64)

    # The 1st pivot point.
    pivot = generate_pivot(order=1, sim_index=sim_index, pdb_limit=True)

    # The CoM of the system.
    com = pipe_centre_of_mass(verbosity=0, missing_error=False)

    # The system for the rotor models.
    if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
        # Generate the axis.
        if sim_index == None:
            axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha,
                                           pivot=pivot,
                                           point=com)
        else:
            axis = create_rotor_axis_alpha(alpha=cdp.axis_alpha_sim[sim_index],
                                           pivot=pivot,
                                           point=com)

        # Create a full normalised axis system.
        frame_from_axis(axis, frame)

    # The system for the isotropic cones.
    elif cdp.model in MODEL_LIST_ISO_CONE:
        # Generate the axis.
        if sim_index == None:
            axis = create_rotor_axis_spherical(theta=cdp.axis_theta,
                                               phi=cdp.axis_phi)
        else:
            axis = create_rotor_axis_spherical(
                theta=cdp.axis_theta_sim[sim_index],
                phi=cdp.axis_phi_sim[sim_index])

        # Create a full normalised axis system.
        frame_from_axis(axis, frame)

    # The system for the pseudo-ellipses and double rotor.
    elif cdp.model in MODEL_LIST_PSEUDO_ELLIPSE + MODEL_LIST_DOUBLE:
        # Generate the eigenframe of the motion.
        if sim_index == None:
            euler_to_R_zyz(cdp.eigen_alpha, cdp.eigen_beta, cdp.eigen_gamma,
                           frame)
        else:
            euler_to_R_zyz(cdp.eigen_alpha_sim[sim_index],
                           cdp.eigen_beta_sim[sim_index],
                           cdp.eigen_gamma_sim[sim_index], frame)

    # Unknown model.
    else:
        raise RelaxFault

    # Return the full eigenframe.
    return frame
Exemple #10
0
def add_cones(structure=None, representation=None, size=None, inc=None, sims=False):
    """Add the cone geometric object for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None or 'A', the standard representation will be created.  If set to 'B', the axis system will be inverted.
    @type representation:       str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword inc:               The number of increments for the filling of the cone objects.
    @type inc:                  int
    @keyword sims:      A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:         bool
    """

    # Create the molecule.
    structure.add_molecule(name='cones')

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i+1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule('cones', model=model_nums[i])

        # The 1st pivot point.
        pivot = generate_pivot(order=1, sim_index=sim_indices[i], pdb_limit=True)

        # The rotation matrix (rotation from the z-axis to the cone axis).
        R = generate_axis_system(sim_index=sim_indices[i])
        print(("Rotation matrix:\n%s" % R))

        # The transformation.
        R = dot(T, R)

        # The pseudo-ellipse cone object.
        if cdp.model in MODEL_LIST_PSEUDO_ELLIPSE:
            if sims:
                cone_obj = Pseudo_elliptic(cdp.cone_theta_x_sim[sim_indices[i]], cdp.cone_theta_y_sim[sim_indices[i]])
            else:
                cone_obj = Pseudo_elliptic(cdp.cone_theta_x, cdp.cone_theta_y)

        # The isotropic cone object.
        else:
            # The angle.
            if hasattr(cdp, 'cone_theta'):
                if sims:
                    cone_theta = cdp.cone_theta_sim[sim_indices[i]]
                else:
                    cone_theta = cdp.cone_theta

            # The object.
            cone_obj = Iso_cone(cone_theta)

        # Create the cone.
        cone(mol=mol, cone_obj=cone_obj, start_res=1, apex=pivot, R=R, inc=inc, scale=size, distribution='regular', axis_flag=False)
Exemple #11
0
def add_axes(structure=None, representation=None, size=None, sims=False):
    """Add the axis system for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None or 'A', the standard representation will be created.  If set to 'B', the axis system will be inverted.
    @type representation:       None or str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation rotors to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # Create the molecule.
    mol_name = 'axes'
    structure.add_molecule(name=mol_name)

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i + 1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The pivot points.
        pivot1 = generate_pivot(order=1,
                                sim_index=sim_indices[i],
                                pdb_limit=True)
        pivot2 = generate_pivot(order=2,
                                sim_index=sim_indices[i],
                                pdb_limit=True)

        # A single z-axis, when no rotor object is present.
        if cdp.model in [MODEL_ISO_CONE_TORSIONLESS]:
            # Print out.
            print("\nGenerating the z-axis system.")

            # The axis.
            if sims:
                axis = create_rotor_axis_spherical(
                    theta=cdp.axis_theta_sim[sim_indices[i]],
                    phi=cdp.axis_phi_sim[sim_indices[i]])
            else:
                axis = create_rotor_axis_spherical(theta=cdp.axis_theta,
                                                   phi=cdp.axis_phi)
            print(("Central axis: %s." % axis))

            # Transform the central axis.
            axis = dot(T, axis)

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            res_num = generate_vector_residues(mol=mol,
                                               vector=axis,
                                               atom_name='z-ax',
                                               res_name_vect='AXE',
                                               res_num=2,
                                               origin=pivot1,
                                               scale=size)

        # The z-axis connecting two motional modes.
        elif cdp.model in [MODEL_DOUBLE_ROTOR]:
            # Printout.
            print("\nGenerating the z-axis linking the two pivot points.")

            # The axis.
            axis = pivot1 - pivot2
            print(("Interconnecting axis: %s." % axis))

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            res_num = generate_vector_residues(mol=mol,
                                               vector=axis,
                                               atom_name='z-ax',
                                               res_name_vect='AXE',
                                               res_num=1,
                                               origin=pivot2)

        # The full axis system.
        elif cdp.model in MODEL_LIST_PSEUDO_ELLIPSE:
            # Print out.
            print("\nGenerating the full axis system.")

            # Add the pivot point.
            mol.atom_add(atom_num=1,
                         atom_name='R',
                         res_name='AXE',
                         res_num=1,
                         pos=pivot1,
                         element='C',
                         pdb_record='HETATM')

            # The axis system.
            axes = generate_axis_system(sim_index=sim_indices[i])

            # Rotations and inversions.
            axes = dot(T, axes)

            # The axes to create.
            label = ['x', 'y']
            if cdp.model in [MODEL_PSEUDO_ELLIPSE_TORSIONLESS]:
                label = ['x', 'y', 'z']

            # Generate the axis vectors.
            print("\nGenerating the axis vectors.")
            for j in range(len(label)):
                res_num = generate_vector_residues(mol=mol,
                                                   vector=axes[:, j],
                                                   atom_name='%s-ax' %
                                                   label[j],
                                                   res_name_vect='AXE',
                                                   res_num=2,
                                                   origin=pivot1,
                                                   scale=size)
Exemple #12
0
def add_rotors(structure=None, representation=None, size=None, sims=False):
    """Add all rotor objects for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None, the rotor will be dumbbell shaped with propellers at both ends.  If set to 'A' or 'B', only half of the rotor will be shown.
    @type representation:       None or str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation rotors to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # Initialise the list structures for the rotor data.
    axis = []
    span = []
    staggered = []
    pivot = []
    rotor_angle = []
    com = []
    label = []
    models = []

    # The half-rotor flag.
    half_rotor = True
    if representation == None:
        half_rotor = False

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i + 1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # The pivot points.
        pivot1 = generate_pivot(order=1,
                                sim_index=sim_indices[i],
                                pdb_limit=True)
        pivot2 = generate_pivot(order=2,
                                sim_index=sim_indices[i],
                                pdb_limit=True)

        # The single rotor models.
        if cdp.model in [
                MODEL_ROTOR, MODEL_FREE_ROTOR, MODEL_ISO_CONE,
                MODEL_ISO_CONE_FREE_ROTOR, MODEL_PSEUDO_ELLIPSE,
                MODEL_PSEUDO_ELLIPSE_FREE_ROTOR
        ]:
            # The rotor angle.
            if cdp.model in MODEL_LIST_FREE_ROTORS:
                rotor_angle.append(pi)
            else:
                if sims:
                    rotor_angle.append(cdp.cone_sigma_max_sim[sim_indices[i]])
                else:
                    rotor_angle.append(cdp.cone_sigma_max)

            # Get the CoM of the entire molecule to use as the centre of the rotor.
            if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
                com.append(
                    pipe_centre_of_mass(verbosity=0, missing_error=False))
            else:
                com.append(pivot1)

            # Generate the rotor axis.
            axes = generate_axis_system(sim_index=sim_indices[i])
            axis.append(axes[:, 2])

            # The size of the rotor (Angstrom), taking the cone representation into account by adding 5 Angstrom.
            if cdp.model in [MODEL_ROTOR, MODEL_FREE_ROTOR]:
                span.append(size)
            else:
                span.append(size + 5.0)

            # Stagger the propeller blades.
            if cdp.model in MODEL_LIST_FREE_ROTORS:
                staggered.append(False)
            else:
                staggered.append(True)

            # The pivot.
            pivot.append(pivot1)

            # The label.
            label.append('z-ax')

            # The models.
            if sims:
                models.append(model_nums[i])
            else:
                models.append(None)

        # The double rotor models.
        elif cdp.model in [MODEL_DOUBLE_ROTOR]:
            # Add both rotor angles (the 2nd must come first).
            if sims:
                rotor_angle.append(cdp.cone_sigma_max_2_sim[sim_indices[i]])
                rotor_angle.append(cdp.cone_sigma_max_sim[sim_indices[i]])
            else:
                rotor_angle.append(cdp.cone_sigma_max_2)
                rotor_angle.append(cdp.cone_sigma_max)

            # Set the com to the pivot points.
            com.append(pivot2)
            com.append(pivot1)

            # Generate the eigenframe of the motion.
            frame = generate_axis_system(sim_index=sim_indices[i])

            # Add the x and y axes.
            axis.append(frame[:, 0])
            axis.append(frame[:, 1])

            # The rotor size (Angstrom).
            span.append(size)
            span.append(size)

            # Stagger the propeller blades.
            staggered.append(True)
            staggered.append(True)

            # The pivot points.
            pivot.append(pivot2)
            pivot.append(pivot1)

            # The labels.
            label.append('x-ax')
            label.append('y-ax')

            # The models.
            if sims:
                models.append(model_nums[i])
                models.append(model_nums[i])
            else:
                models.append(None)
                models.append(None)

    # Add each rotor to the structure as a new molecule.
    for i in range(len(axis)):
        rotor(structure=structure,
              rotor_angle=rotor_angle[i],
              axis=dot(T, axis[i]),
              axis_pt=pivot[i],
              label=label[i],
              centre=com[i],
              span=span[i] / 1e10,
              blade_length=5e-10,
              model_num=models[i],
              staggered=staggered[i],
              half_rotor=half_rotor)
Exemple #13
0
def add_titles(structure=None,
               representation=None,
               displacement=40.0,
               sims=False):
    """Add atoms to be used for the titles for the frame order geometric objects.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to title.
    @type representation:       None or str
    @keyword displacement:      The distance away from the pivot point, in Angstrom, to place the title.  The simulation title will be shifted by a few extra Angstrom to avoid clashes.
    @type displacement:         float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # The title atom names.
    atom_name = None
    if representation == None and sims:
        atom_name = 'mc'
    elif representation == 'A':
        if sims:
            atom_name = 'mc-a'
        else:
            atom_name = 'a'
    elif representation == 'B':
        if sims:
            atom_name = 'mc-b'
        else:
            atom_name = 'b'

    # Nothing to do.
    if atom_name == None:
        return

    # Avoid name overlaps.
    if sims:
        displacement += 3

    # Create the molecule.
    mol_name = 'titles'
    structure.add_molecule(name=mol_name)

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The pivot points.
    pivot1 = generate_pivot(order=1, pdb_limit=True)
    pivot2 = generate_pivot(order=2, pdb_limit=True)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i + 1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The axis system.
        axes = generate_axis_system(sim_index=sim_indices[i])

        # Transform the central axis.
        axis = dot(T, axes[:, 2])

        # The label position.
        pos = pivot1 + displacement * axis

        # Add the atom.
        mol.atom_add(atom_name=atom_name,
                     res_name='TLE',
                     res_num=1,
                     pos=pos,
                     element='Ti',
                     pdb_record='HETATM')
Exemple #14
0
def simulate(file="simulation.pdb.bz2", dir=None, step_size=2.0, snapshot=10, total=1000, model=1, force=True):
    """Pseudo-Brownian dynamics simulation of the frame order motions.

    @keyword file:      The PDB file for storing the frame order pseudo-Brownian dynamics simulation.  The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.
    @type file:         str
    @keyword dir:       The directory name to place the file into.
    @type dir:          str or None
    @keyword step_size: The rotation will be of a random direction but with this fixed angle.  The value is in degrees.
    @type step_size:    float
    @keyword snapshot:  The number of steps in the simulation when snapshots will be taken.
    @type snapshot:     int
    @keyword total:     The total number of snapshots to take before stopping the simulation.
    @type total:        int
    @keyword model:     Only one model from an analysed ensemble of structures can be used for the pseudo-Brownian simulation, as the simulation and corresponding PDB file consists of one model per simulation.
    @type model:        int
    @keyword force:     A flag which, if set to True, will overwrite the any pre-existing file.
    @type force:        bool
    """

    # Printout.
    print("Pseudo-Brownian dynamics simulation of the frame order motions.")

    # Checks.
    check_pipe()
    check_model()
    check_domain()
    check_parameters()
    check_pivot()

    # Skip the rigid model.
    if cdp.model == MODEL_RIGID:
        print("Skipping the rigid model.")
        return

    # Open the output file.
    file = open_write_file(file_name=file, dir=dir, force=force)

    # The parameter values.
    values = assemble_param_vector()
    params = {}
    i = 0
    for name in cdp.params:
        params[name] = values[i]
        i += 1

    # The structure.
    structure = deepcopy(cdp.structure)
    if structure.num_models() > 1:
        structure.collapse_ensemble(model_num=model)

    # The pivot points.
    num_states = 1
    if cdp.model == MODEL_DOUBLE_ROTOR:
        num_states = 2
    pivot = zeros((num_states, 3), float64)
    for i in range(num_states):
        pivot[i] = generate_pivot(order=i+1, pdb_limit=True)

    # Shift to the average position.
    average_position(structure=structure, models=[None])

    # The motional eigenframe.
    frame = generate_axis_system()

    # Create the distribution.
    brownian(file=file, model=cdp.model, structure=structure, parameters=params, eigenframe=frame, pivot=pivot, atom_id=domain_moving(), step_size=step_size, snapshot=snapshot, total=total)

    # Close the file.
    file.close()
Exemple #15
0
def add_titles(structure=None, representation=None, displacement=40.0, sims=False):
    """Add atoms to be used for the titles for the frame order geometric objects.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to title.
    @type representation:       None or str
    @keyword displacement:      The distance away from the pivot point, in Angstrom, to place the title.  The simulation title will be shifted by a few extra Angstrom to avoid clashes.
    @type displacement:         float
    @keyword sims:              A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:                 bool
    """

    # The title atom names.
    atom_name = None
    if representation == None and sims:
        atom_name = 'mc'
    elif representation == 'A':
        if sims:
            atom_name = 'mc-a'
        else:
            atom_name = 'a'
    elif representation == 'B':
        if sims:
            atom_name = 'mc-b'
        else:
            atom_name = 'b'

    # Nothing to do.
    if atom_name == None:
        return

    # Avoid name overlaps.
    if sims:
        displacement += 3

    # Create the molecule.
    mol_name = 'titles'
    structure.add_molecule(name=mol_name)

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The pivot points.
    pivot1 = generate_pivot(order=1, pdb_limit=True)
    pivot2 = generate_pivot(order=2, pdb_limit=True)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i+1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule(mol_name, model=model_nums[i])

        # The axis system.
        axes = generate_axis_system(sim_index=sim_indices[i])

        # Transform the central axis.
        axis = dot(T, axes[:, 2])

        # The label position.
        pos = pivot1 + displacement*axis

        # Add the atom.
        mol.atom_add(atom_name=atom_name, res_name='TLE', res_num=1, pos=pos, element='Ti', pdb_record='HETATM')
Exemple #16
0
def distribute(file="distribution.pdb.bz2", dir=None, atom_id=None, total=1000, max_rotations=100000, model=1, force=True):
    """Create a uniform distribution of structures for the frame order motions.

    @keyword file:          The PDB file for storing the frame order motional distribution.  The compression is determined automatically by the file extensions '*.pdb', '*.pdb.gz', and '*.pdb.bz2'.
    @type file:             str
    @keyword dir:           The directory name to place the file into.
    @type dir:              str or None
    @keyword atom_id:       The atom identification string to allow the distribution to be a subset of all atoms.
    @type atom_id:          None or str
    @keyword total:         The total number of states/model/structures in the distribution.
    @type total:            int
    @keyword max_rotations: The maximum number of rotations to generate the distribution from.  This prevents an execution for an infinite amount of time when a frame order amplitude parameter is close to zero so that the subset of all rotations within the distribution is close to zero.
    @type max_rotations:    int
    @keyword model:         Only one model from an analysed ensemble of structures can be used for the distribution, as the corresponding PDB file consists of one model per state.
    @type model:            int
    @keyword force:         A flag which, if set to True, will overwrite the any pre-existing file.
    @type force:            bool
    """

    # Printout.
    print("Uniform distribution of structures representing the frame order motions.")

    # Check the total.
    if total > 9999:
        raise RelaxError("A maximum of 9999 models is allowed in the PDB format.")

    # Checks.
    check_pipe()
    check_model()
    check_domain()
    check_parameters()
    check_pivot()

    # Skip the rigid model.
    if cdp.model == MODEL_RIGID:
        print("Skipping the rigid model.")
        return

    # Open the output file.
    file = open_write_file(file_name=file, dir=dir, force=force)

    # The parameter values.
    values = assemble_param_vector()
    params = {}
    i = 0
    for name in cdp.params:
        params[name] = values[i]
        i += 1

    # The structure.
    structure = deepcopy(cdp.structure)
    if structure.num_models() > 1:
        structure.collapse_ensemble(model_num=model)

    # The pivot points.
    num_states = 1
    if cdp.model == MODEL_DOUBLE_ROTOR:
        num_states = 2
    pivot = zeros((num_states, 3), float64)
    for i in range(num_states):
        pivot[i] = generate_pivot(order=i+1, pdb_limit=True)

    # Shift to the average position.
    average_position(structure=structure, models=[None])

    # The motional eigenframe.
    frame = generate_axis_system()

    # Only work with a subset.
    if atom_id:
        # The inverted selection.
        selection = structure.selection(atom_id=atom_id, inv=True)

        # Delete the data.
        structure.delete(selection=selection, verbosity=0)

    # Create the distribution.
    uniform_distribution(file=file, model=cdp.model, structure=structure, parameters=params, eigenframe=frame, pivot=pivot, atom_id=domain_moving(), total=total, max_rotations=max_rotations)

    # Close the file.
    file.close()
Exemple #17
0
def add_cones(structure=None,
              representation=None,
              size=None,
              inc=None,
              sims=False):
    """Add the cone geometric object for the current frame order model to the structural object.

    @keyword structure:         The internal structural object to add the rotor objects to.
    @type structure:            lib.structure.internal.object.Internal instance
    @keyword representation:    The representation to create.  If this is set to None or 'A', the standard representation will be created.  If set to 'B', the axis system will be inverted.
    @type representation:       str
    @keyword size:              The size of the geometric object in Angstroms.
    @type size:                 float
    @keyword inc:               The number of increments for the filling of the cone objects.
    @type inc:                  int
    @keyword sims:      A flag which if True will add the Monte Carlo simulation pivots to the structural object.  There must be one model for each Monte Carlo simulation already present in the structural object.
    @type sims:         bool
    """

    # Create the molecule.
    structure.add_molecule(name='cones')

    # The transformation matrix (identity matrix or inversion matrix).
    if representation == 'B':
        T = -eye(3)
    else:
        T = eye(3)

    # The models to loop over.
    model_nums = [None]
    sim_indices = [None]
    if sims:
        model_nums = [i + 1 for i in range(cdp.sim_number)]
        sim_indices = list(range(cdp.sim_number))

    # Loop over the models.
    for i in range(len(model_nums)):
        # Alias the molecule.
        mol = structure.get_molecule('cones', model=model_nums[i])

        # The 1st pivot point.
        pivot = generate_pivot(order=1,
                               sim_index=sim_indices[i],
                               pdb_limit=True)

        # The rotation matrix (rotation from the z-axis to the cone axis).
        R = generate_axis_system(sim_index=sim_indices[i])
        print(("Rotation matrix:\n%s" % R))

        # The transformation.
        R = dot(T, R)

        # The pseudo-ellipse cone object.
        if cdp.model in MODEL_LIST_PSEUDO_ELLIPSE:
            if sims:
                cone_obj = Pseudo_elliptic(
                    cdp.cone_theta_x_sim[sim_indices[i]],
                    cdp.cone_theta_y_sim[sim_indices[i]])
            else:
                cone_obj = Pseudo_elliptic(cdp.cone_theta_x, cdp.cone_theta_y)

        # The isotropic cone object.
        else:
            # The angle.
            if hasattr(cdp, 'cone_theta'):
                if sims:
                    cone_theta = cdp.cone_theta_sim[sim_indices[i]]
                else:
                    cone_theta = cdp.cone_theta

            # The object.
            cone_obj = Iso_cone(cone_theta)

        # Create the cone.
        cone(mol=mol,
             cone_obj=cone_obj,
             start_res=1,
             apex=pivot,
             R=R,
             inc=inc,
             scale=size,
             distribution='regular',
             axis_flag=False)