예제 #1
0
파일: api.py 프로젝트: tlinnet/relax
    def sim_init_values(self):
        """Initialise the Monte Carlo parameter values."""

        # Get the minimisation statistic object names.
        sim_names = self.data_names(set='min')

        # Add the paramagnetic centre, if optimised.
        if hasattr(cdp,
                   'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
            sim_names += ['paramagnetic_centre']

        # Alignments.
        if hasattr(cdp, 'align_tensors'):
            # The parameter names.
            names = ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz']

            # Loop over the alignments, adding the alignment tensor parameters to the tensor data container.
            for i in range(len(cdp.align_tensors)):
                # Skip non-optimised tensors.
                if not opt_uses_tensor(cdp.align_tensors[i]):
                    continue

                # Set up the number of simulations.
                cdp.align_tensors[i].set_sim_num(cdp.sim_number)

                # Loop over all the parameter names, setting the initial simulation values to those of the parameter value.
                for object_name in names:
                    for j in range(cdp.sim_number):
                        cdp.align_tensors[i].set(param=object_name,
                                                 value=deepcopy(
                                                     getattr(
                                                         cdp.align_tensors[i],
                                                         object_name)),
                                                 category='sim',
                                                 sim_index=j)

            # Create all other simulation objects.
            for object_name in sim_names:
                # Name for the simulation object.
                sim_object_name = object_name + '_sim'

                # Create the simulation object.
                setattr(cdp, sim_object_name, [])

                # Get the simulation object.
                sim_object = getattr(cdp, sim_object_name)

                # Loop over the simulations.
                for j in range(cdp.sim_number):
                    # Append None to fill the structure.
                    sim_object.append(None)

            # Set the simulation paramagnetic centre positions to the optimised values.
            if hasattr(
                    cdp,
                    'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
                for j in range(cdp.sim_number):
                    cdp.paramagnetic_centre_sim[j] = deepcopy(
                        cdp.paramagnetic_centre)
예제 #2
0
def assemble_scaling_matrix(data_types=None, scaling=True):
    """Create and return the scaling matrix.

    @keyword data_types:    The base data types used in the optimisation.  This list can contain
                            the elements 'rdc', 'pcs' or 'tensor'.
    @type data_types:       list of str
    @keyword scaling:       If False, then the identity matrix will be returned.
    @type scaling:          bool
    @return:                The square and diagonal scaling matrix.
    @rtype:                 numpy rank-2 array
    """

    # Initialise.
    scaling_matrix = identity(param_num(), float64)

    # Return the identity matrix.
    if not scaling:
        return scaling_matrix

    # Starting point of the populations.
    pop_start = 0

    # Loop over the alignments.
    tensor_num = 0
    for i in range(len(cdp.align_tensors)):
        # Skip non-optimised tensors.
        if not opt_uses_tensor(cdp.align_tensors[i]):
            continue

        # Add the 5 alignment parameters.
        pop_start = pop_start + 5

        # The alignment parameters.
        for j in range(5):
            scaling_matrix[5*tensor_num + j, 5*tensor_num + j] = 1.0

        # Increase the tensor number.
        tensor_num += 1

    # Loop over the populations, and set the scaling factor.
    if cdp.model in ['2-domain', 'population']:
        factor = 0.1
        for i in range(pop_start, pop_start + (cdp.N-1)):
            scaling_matrix[i, i] = factor

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        for i in range(-3, 0):
            scaling_matrix[i, i] = 1e2

    # Return the matrix.
    return scaling_matrix
예제 #3
0
파일: api.py 프로젝트: pombredanne/relax
    def sim_init_values(self):
        """Initialise the Monte Carlo parameter values."""

        # Get the minimisation statistic object names.
        sim_names = self.data_names(set='min')

        # Add the paramagnetic centre, if optimised.
        if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
            sim_names += ['paramagnetic_centre']

        # Alignments.
        if hasattr(cdp, 'align_tensors'):
            # The parameter names.
            names = ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz']

            # Loop over the alignments, adding the alignment tensor parameters to the tensor data container.
            for i in range(len(cdp.align_tensors)):
                # Skip non-optimised tensors.
                if not opt_uses_tensor(cdp.align_tensors[i]):
                    continue

                # Set up the number of simulations.
                cdp.align_tensors[i].set_sim_num(cdp.sim_number)

                # Loop over all the parameter names, setting the initial simulation values to those of the parameter value.
                for object_name in names:
                    for j in range(cdp.sim_number):
                        cdp.align_tensors[i].set(param=object_name, value=deepcopy(getattr(cdp.align_tensors[i], object_name)), category='sim', sim_index=j)

            # Create all other simulation objects.
            for object_name in sim_names:
                # Name for the simulation object.
                sim_object_name = object_name + '_sim'

                # Create the simulation object.
                setattr(cdp, sim_object_name, [])

                # Get the simulation object.
                sim_object = getattr(cdp, sim_object_name)

                # Loop over the simulations.
                for j in range(cdp.sim_number):
                    # Append None to fill the structure.
                    sim_object.append(None)

            # Set the simulation paramagnetic centre positions to the optimised values.
            if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
                for j in range(cdp.sim_number):
                    cdp.paramagnetic_centre_sim[j] = deepcopy(cdp.paramagnetic_centre)
예제 #4
0
파일: api.py 프로젝트: tlinnet/relax
    def get_param_names(self, model_info=None):
        """Return a vector of parameter names.

        @keyword model_info:    The model information from model_loop().  This is unused.
        @type model_info:       None
        @return:                The vector of parameter names.
        @rtype:                 list of str
        """

        # Init.
        param_names = []

        # A RDC or PCS data type requires the alignment tensors to be at the start of the parameter vector (unless the tensors are fixed).
        if opt_uses_align_data():
            for i in range(len(cdp.align_tensors)):
                # Skip non-optimised tensors.
                if not opt_uses_tensor(cdp.align_tensors[i]):
                    continue

                # Add the parameters.
                param_names += ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz']

        # Populations.
        if cdp.model in ['2-domain', 'population']:
            for i in range(cdp.N - 1):
                param_names.append('probs')

        # The Euler angles.
        if cdp.model == '2-domain':
            for i in range(cdp.N):
                param_names.append('alpha')
                param_names.append('beta')
                param_names.append('gamma')

        # The paramagnetic centre.
        if hasattr(cdp,
                   'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
            for i in range(3):
                param_names.append('paramagnetic_centre')

        # Return the list.
        return param_names
예제 #5
0
파일: api.py 프로젝트: pombredanne/relax
    def get_param_names(self, model_info=None):
        """Return a vector of parameter names.

        @keyword model_info:    The model information from model_loop().  This is unused.
        @type model_info:       None
        @return:                The vector of parameter names.
        @rtype:                 list of str
        """

        # Init.
        param_names = []

        # A RDC or PCS data type requires the alignment tensors to be at the start of the parameter vector (unless the tensors are fixed).
        if opt_uses_align_data():
            for i in range(len(cdp.align_tensors)):
                # Skip non-optimised tensors.
                if not opt_uses_tensor(cdp.align_tensors[i]):
                    continue

                # Add the parameters.
                param_names += ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz']

        # Populations.
        if cdp.model in ['2-domain', 'population']:
            for i in range(cdp.N - 1):
                param_names.append('probs')

        # The Euler angles.
        if cdp.model == '2-domain':
            for i in range(cdp.N):
                param_names.append('alpha')
                param_names.append('beta')
                param_names.append('gamma')

        # The paramagnetic centre.
        if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
            for i in range(3):
                param_names.append('paramagnetic_centre')

        # Return the list.
        return param_names
예제 #6
0
def param_num():
    """Determine the number of parameters in the model.

    @return:    The number of model parameters.
    @rtype:     int
    """

    # Determine the data type.
    data_types = base_data_types()

    # Init.
    num = 0

    # Alignment tensor params.
    if ('rdc' in data_types
            or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments.
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Add 5 tensor parameters.
            num += 5

    # Populations.
    if cdp.model in ['2-domain', 'population']:
        num = num + (cdp.N - 1)

    # Euler angles.
    if cdp.model == '2-domain':
        num = num + 3 * cdp.N

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        num = num + 3

    # Return the param number.
    return num
예제 #7
0
def param_num():
    """Determine the number of parameters in the model.

    @return:    The number of model parameters.
    @rtype:     int
    """

    # Determine the data type.
    data_types = base_data_types()

    # Init.
    num = 0

    # Alignment tensor params.
    if ('rdc' in data_types or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments.
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Add 5 tensor parameters.
            num += 5

    # Populations.
    if cdp.model in ['2-domain', 'population']:
        num = num + (cdp.N - 1)

    # Euler angles.
    if cdp.model == '2-domain':
        num = num + 3*cdp.N

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        num = num + 3

     # Return the param number.
    return num
예제 #8
0
def opt_uses_rdc(align_id):
    """Determine if the RDC data for the given alignment ID is needed for optimisation.

    @param align_id:    The alignment ID string.
    @type align_id:     str
    @return:            True if the RDC data is to be used for optimisation, False otherwise.
    @rtype:             bool
    """

    # No alignment IDs.
    if not hasattr(cdp, 'rdc_ids'):
        return False

    # No RDC data for the alignment.
    if align_id not in cdp.rdc_ids:
        return False

    # Is the tensor optimised?
    tensor_flag = opt_uses_tensor(get_tensor_object(align_id))

    # Is the paramagnetic position optimised?
    pos_flag = False
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        pos_flag = True

    # Are the populations optimised?
    prob_flag = False
    if cdp.model == 'population':
        prob_flag = True

    # Not used.
    if not tensor_flag and not pos_flag and not prob_flag:
        return False

    # The RDC data is to be used for optimisation.
    return True
예제 #9
0
def minimise_bc_data(model, sim_index=None):
    """Extract and unpack the back calculated data.

    @param model:       The instantiated class containing the target function.
    @type model:        class instance
    @keyword sim_index: The optional Monte Carlo simulation index.
    @type sim_index:    None or int
    """

    # No alignment tensors, so nothing to do.
    if not hasattr(cdp, 'align_tensors'):
        return

    # Simulation flag.
    sim_flag = (sim_index != None)

    # Loop over each alignment.
    align_index = 0
    for i in range(len(cdp.align_ids)):
        # Skip non-optimised tensors.
        if not opt_uses_tensor(cdp.align_tensors[i]):
            continue

        # The alignment ID.
        align_id = cdp.align_ids[i]

        # Data flags
        rdc_flag = False
        if hasattr(cdp, 'rdc_ids') and align_id in cdp.rdc_ids:
            rdc_flag = True
        pcs_flag = False
        if hasattr(cdp, 'pcs_ids') and align_id in cdp.pcs_ids:
            pcs_flag = True

        # Spin loop.
        pcs_index = 0
        for spin in spin_loop():
            # Skip deselected spins.
            if not spin.select:
                continue

            # Spins with PCS data.
            if pcs_flag and hasattr(spin, 'pcs'):
                # Initialise the data structure if necessary.
                if sim_flag:
                    if not hasattr(spin, 'pcs_sim_bc'):
                        spin.pcs_sim_bc = {}
                    if align_id not in spin.pcs_sim_bc:
                        spin.pcs_sim_bc[align_id] = [None] * cdp.sim_number
                else:
                    if not hasattr(spin, 'pcs_bc'):
                        spin.pcs_bc = {}

                # Add the back calculated PCS (in ppm).
                if sim_flag:
                    spin.pcs_sim_bc[align_id][sim_index] = model.deltaij_theta[align_index, pcs_index] * 1e6
                else:
                    spin.pcs_bc[align_id] = model.deltaij_theta[align_index, pcs_index] * 1e6

                # Increment the data index if the spin container has data.
                pcs_index = pcs_index + 1

        # Interatomic data container loop.
        rdc_index = 0
        for interatom in interatomic_loop():
            # Get the spins.
            spin1 = return_spin(interatom.spin_id1)
            spin2 = return_spin(interatom.spin_id2)

            # RDC checks.
            if not check_rdcs(interatom):
                continue

            # Containers with RDC data.
            if rdc_flag and hasattr(interatom, 'rdc'):
                # Initialise the data structure if necessary.
                if sim_flag:
                    if not hasattr(interatom, 'rdc_sim_bc'):
                        interatom.rdc_sim_bc = {}
                    if align_id not in interatom.rdc_sim_bc:
                        interatom.rdc_sim_bc[align_id] = [0.0] * cdp.sim_number
                else:
                    if not hasattr(interatom, 'rdc_bc'):
                        interatom.rdc_bc = {}

                # Append the back calculated PCS.
                if sim_flag:
                    interatom.rdc_sim_bc[align_id][sim_index] = model.rdc_theta[align_index, rdc_index]
                else:
                    interatom.rdc_bc[align_id] = model.rdc_theta[align_index, rdc_index]

                # Increment the data index if the interatom container has data.
                rdc_index = rdc_index + 1

        # Increment the alignment index (for the optimised tensors).
        align_index += 1
예제 #10
0
def minimise_bc_data(model, sim_index=None):
    """Extract and unpack the back calculated data.

    @param model:       The instantiated class containing the target function.
    @type model:        class instance
    @keyword sim_index: The optional Monte Carlo simulation index.
    @type sim_index:    None or int
    """

    # No alignment tensors, so nothing to do.
    if not hasattr(cdp, 'align_tensors'):
        return

    # Simulation flag.
    sim_flag = (sim_index != None)

    # Loop over each alignment.
    align_index = 0
    for i in range(len(cdp.align_ids)):
        # Skip non-optimised tensors.
        if not opt_uses_tensor(cdp.align_tensors[i]):
            continue

        # The alignment ID.
        align_id = cdp.align_ids[i]

        # Data flags
        rdc_flag = False
        if hasattr(cdp, 'rdc_ids') and align_id in cdp.rdc_ids:
            rdc_flag = True
        pcs_flag = False
        if hasattr(cdp, 'pcs_ids') and align_id in cdp.pcs_ids:
            pcs_flag = True

        # Spin loop.
        pcs_index = 0
        for spin in spin_loop():
            # Skip deselected spins.
            if not spin.select:
                continue

            # Spins with PCS data.
            if pcs_flag and hasattr(spin, 'pcs'):
                # Initialise the data structure if necessary.
                if sim_flag:
                    if not hasattr(spin, 'pcs_sim_bc'):
                        spin.pcs_sim_bc = {}
                    if align_id not in spin.pcs_sim_bc:
                        spin.pcs_sim_bc[align_id] = [None] * cdp.sim_number
                else:
                    if not hasattr(spin, 'pcs_bc'):
                        spin.pcs_bc = {}

                # Add the back calculated PCS (in ppm).
                if sim_flag:
                    spin.pcs_sim_bc[align_id][sim_index] = model.deltaij_theta[
                        align_index, pcs_index] * 1e6
                else:
                    spin.pcs_bc[align_id] = model.deltaij_theta[
                        align_index, pcs_index] * 1e6

                # Increment the data index if the spin container has data.
                pcs_index = pcs_index + 1

        # Interatomic data container loop.
        rdc_index = 0
        for interatom in interatomic_loop():
            # Get the spins.
            spin1 = return_spin(spin_hash=interatom._spin_hash1)
            spin2 = return_spin(spin_hash=interatom._spin_hash2)

            # RDC checks.
            if not check_rdcs(interatom):
                continue

            # Containers with RDC data.
            if rdc_flag and hasattr(interatom, 'rdc'):
                # Initialise the data structure if necessary.
                if sim_flag:
                    if not hasattr(interatom, 'rdc_sim_bc'):
                        interatom.rdc_sim_bc = {}
                    if align_id not in interatom.rdc_sim_bc:
                        interatom.rdc_sim_bc[align_id] = [0.0] * cdp.sim_number
                else:
                    if not hasattr(interatom, 'rdc_bc'):
                        interatom.rdc_bc = {}

                # Append the back calculated PCS.
                if sim_flag:
                    interatom.rdc_sim_bc[align_id][
                        sim_index] = model.rdc_theta[align_index, rdc_index]
                else:
                    interatom.rdc_bc[align_id] = model.rdc_theta[align_index,
                                                                 rdc_index]

                # Increment the data index if the interatom container has data.
                rdc_index = rdc_index + 1

        # Increment the alignment index (for the optimised tensors).
        align_index += 1
예제 #11
0
def assemble_param_vector(sim_index=None):
    """Assemble all the parameters of the model into a single array.

    @param sim_index:       The index of the simulation to optimise.  This should be None if normal optimisation is desired.
    @type sim_index:        None or int
    @return:                The parameter vector used for optimisation.
    @rtype:                 numpy array
    """

    # Test if the model is selected.
    if not hasattr(cdp, 'model') or not isinstance(cdp.model, str):
        raise RelaxNoModelError

    # Determine the data type.
    data_types = base_data_types()

    # Initialise the parameter vector.
    param_vector = []

    # A RDC or PCS data type requires the alignment tensors to be at the start of the parameter vector (unless the tensors are fixed).
    if opt_uses_align_data():
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # No values set.
            if not hasattr(cdp.align_tensors[i], 'A_5D'):
                param_vector += [None, None, None, None, None]

            # Otherwise add the parameters.
            else:
                param_vector += list(cdp.align_tensors[i].A_5D)

    # Monte Carlo simulation data structures.
    if sim_index != None:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs_sim[sim_index]

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha_sim[sim_index]
            beta = cdp.beta_sim[sim_index]
            gamma = cdp.gamma_sim[sim_index]

    # Normal data structures.
    else:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha
            beta = cdp.beta
            gamma = cdp.gamma

    # The probabilities (exclude that of state N).
    if cdp.model in ['2-domain', 'population']:
        param_vector = param_vector + probs[0:-1]

    # The Euler angles.
    if cdp.model == '2-domain':
        for i in range(cdp.N):
            param_vector.append(alpha[i])
            param_vector.append(beta[i])
            param_vector.append(gamma[i])

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        if not hasattr(cdp, 'paramagnetic_centre'):
            for i in range(3):
                param_vector.append(None)
        elif sim_index != None:
            if cdp.paramagnetic_centre_sim[sim_index] is None:
                for i in range(3):
                    param_vector.append(None)
            else:
                for i in range(3):
                    param_vector.append(
                        cdp.paramagnetic_centre_sim[sim_index][i])
        else:
            for i in range(3):
                param_vector.append(cdp.paramagnetic_centre[i])

    # Return a numpy arrary.
    return array(param_vector, float64)
예제 #12
0
def linear_constraints(data_types=None, scaling_matrix=None):
    """Function for setting up the linear constraint matrices A and b.

    Standard notation
    =================

    The N-state model constraints are::

        0 <= pc <= 1,

    where p is the probability and c corresponds to state c.


    Matrix notation
    ===============

    In the notation A.x >= b, where A is an matrix of coefficients, x is an array of parameter
    values, and b is a vector of scalars, these inequality constraints are::

        | 1  0  0 |                   |    0    |
        |         |                   |         |
        |-1  0  0 |                   |   -1    |
        |         |                   |         |
        | 0  1  0 |                   |    0    |
        |         |     |  p0  |      |         |
        | 0 -1  0 |     |      |      |   -1    |
        |         |  .  |  p1  |  >=  |         |
        | 0  0  1 |     |      |      |    0    |
        |         |     |  p2  |      |         |
        | 0  0 -1 |                   |   -1    |
        |         |                   |         |
        |-1 -1 -1 |                   |   -1    |
        |         |                   |         |
        | 1  1  1 |                   |    0    |

    This example is for a 4-state model, the last probability pn is not included as this
    parameter does not exist (because the sum of pc is equal to 1).  The Euler angle parameters
    have been excluded here but will be included in the returned A and b objects.  These
    parameters simply add columns of zero to the A matrix and have no effect on b.  The last two
    rows correspond to the inequality::

        0 <= pN <= 1.

    As::
                N-1
                \
        pN = 1 - >  pc,
                /__
                c=1

    then::

        -p1 - p2 - ... - p(N-1) >= -1,

         p1 + p2 + ... + p(N-1) >= 0.


    @keyword data_types:        The base data types used in the optimisation.  This list can
                                contain the elements 'rdc', 'pcs' or 'tensor'.
    @type data_types:           list of str
    @keyword scaling_matrix:    The diagonal scaling matrix.
    @type scaling_matrix:       numpy rank-2 square matrix
    @return:                    The matrices A and b.
    @rtype:                     tuple of len 2 of a numpy rank-2, size NxM matrix and numpy
                                rank-1, size N array
    """

    # Starting point of the populations.
    pop_start = 0
    if ('rdc' in data_types
            or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments.
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Add 5 parameters.
            pop_start += 5

    # Initialisation (0..j..m).
    A = []
    b = []
    zero_array = zeros(param_num(), float64)
    i = pop_start
    j = 0

    # Probability parameters.
    if cdp.model in ['2-domain', 'population']:
        # Loop over the prob parameters (N - 1, because the sum of pc is 1).
        for k in range(cdp.N - 1):
            # 0 <= pc <= 1.
            A.append(zero_array * 0.0)
            A.append(zero_array * 0.0)
            A[j][i] = 1.0
            A[j + 1][i] = -1.0
            b.append(0.0)
            b.append(-1.0 / scaling_matrix[i, i])
            j = j + 2

            # Increment i.
            i = i + 1

        # Add the inequalities for pN.
        A.append(zero_array * 0.0)
        A.append(zero_array * 0.0)
        for i in range(pop_start, pop_start + cdp.N - 1):
            A[-2][i] = -1.0
            A[-1][i] = 1.0
        b.append(-1.0 / scaling_matrix[i, i])
        b.append(0.0)

    # Convert to numpy data structures.
    A = array(A, float64)
    b = array(b, float64)

    # Return the constraint objects.
    return A, b
예제 #13
0
def disassemble_param_vector(param_vector=None,
                             data_types=None,
                             sim_index=None):
    """Disassemble the parameter vector and place the values into the relevant variables.

    For the 2-domain N-state model, the parameters are stored in the probability and Euler angle data structures.  For the population N-state model, only the probabilities are stored.  If RDCs are present and alignment tensors are optimised, then these are stored as well.

    @keyword data_types:    The base data types used in the optimisation.  This list can contain the elements 'rdc', 'pcs' or 'tensor'.
    @type data_types:       list of str
    @keyword param_vector:  The parameter vector returned from optimisation.
    @type param_vector:     numpy array
    @keyword sim_index:     The index of the simulation to optimise.  This should be None if normal optimisation is desired.
    @type sim_index:        None or int
    """

    # Test if the model is selected.
    if not hasattr(cdp, 'model') or not isinstance(cdp.model, str):
        raise RelaxNoModelError

    # Unpack and strip off the alignment tensor parameters.
    if ('rdc' in data_types
            or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments, adding the alignment tensor parameters to the tensor data container.
        tensor_num = 0
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Normal tensors.
            if sim_index == None:
                cdp.align_tensors[i].set(param='Axx',
                                         value=param_vector[5 * tensor_num])
                cdp.align_tensors[i].set(param='Ayy',
                                         value=param_vector[5 * tensor_num +
                                                            1])
                cdp.align_tensors[i].set(param='Axy',
                                         value=param_vector[5 * tensor_num +
                                                            2])
                cdp.align_tensors[i].set(param='Axz',
                                         value=param_vector[5 * tensor_num +
                                                            3])
                cdp.align_tensors[i].set(param='Ayz',
                                         value=param_vector[5 * tensor_num +
                                                            4])

            # Monte Carlo simulated tensors.
            else:
                cdp.align_tensors[i].set(param='Axx',
                                         value=param_vector[5 * tensor_num],
                                         category='sim',
                                         sim_index=sim_index)
                cdp.align_tensors[i].set(param='Ayy',
                                         value=param_vector[5 * tensor_num +
                                                            1],
                                         category='sim',
                                         sim_index=sim_index)
                cdp.align_tensors[i].set(param='Axy',
                                         value=param_vector[5 * tensor_num +
                                                            2],
                                         category='sim',
                                         sim_index=sim_index)
                cdp.align_tensors[i].set(param='Axz',
                                         value=param_vector[5 * tensor_num +
                                                            3],
                                         category='sim',
                                         sim_index=sim_index)
                cdp.align_tensors[i].set(param='Ayz',
                                         value=param_vector[5 * tensor_num +
                                                            4],
                                         category='sim',
                                         sim_index=sim_index)

            # Increase the tensor number.
            tensor_num += 1

        # Create a new parameter vector without the tensors.
        param_vector = param_vector[5 * tensor_num:]

    # Alias the Monte Carlo simulation data structures.
    if sim_index != None:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs_sim[sim_index]

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha_sim[sim_index]
            beta = cdp.beta_sim[sim_index]
            gamma = cdp.gamma_sim[sim_index]

    # Alias the normal data structures.
    else:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha
            beta = cdp.beta
            gamma = cdp.gamma

    # Set the probabilities for states 0 to N-1 in the aliased structures.
    if cdp.model in ['2-domain', 'population']:
        for i in range(cdp.N - 1):
            probs[i] = param_vector[i]

        # The probability for state N.
        probs[-1] = 1 - sum(probs[0:-1])

    # Set the Euler angles in the aliased structures.
    if cdp.model == '2-domain':
        for i in range(cdp.N):
            alpha[i] = param_vector[cdp.N - 1 + 3 * i]
            beta[i] = param_vector[cdp.N - 1 + 3 * i + 1]
            gamma[i] = param_vector[cdp.N - 1 + 3 * i + 2]

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        # Create the structure if needed.
        if not hasattr(cdp, 'paramagnetic_centre'):
            cdp.paramagnetic_centre = zeros(3, float64)

        # The position.
        if sim_index == None:
            cdp.paramagnetic_centre[0] = param_vector[-3]
            cdp.paramagnetic_centre[1] = param_vector[-2]
            cdp.paramagnetic_centre[2] = param_vector[-1]

        # Monte Carlo simulated positions.
        else:
            if cdp.paramagnetic_centre_sim[sim_index] is None:
                cdp.paramagnetic_centre_sim[sim_index] = [None, None, None]
            cdp.paramagnetic_centre_sim[sim_index][0] = param_vector[-3]
            cdp.paramagnetic_centre_sim[sim_index][1] = param_vector[-2]
            cdp.paramagnetic_centre_sim[sim_index][2] = param_vector[-1]
예제 #14
0
def assemble_param_vector(sim_index=None):
    """Assemble all the parameters of the model into a single array.

    @param sim_index:       The index of the simulation to optimise.  This should be None if normal optimisation is desired.
    @type sim_index:        None or int
    @return:                The parameter vector used for optimisation.
    @rtype:                 numpy array
    """

    # Test if the model is selected.
    if not hasattr(cdp, 'model') or not isinstance(cdp.model, str):
        raise RelaxNoModelError

    # Determine the data type.
    data_types = base_data_types()

    # Initialise the parameter vector.
    param_vector = []

    # A RDC or PCS data type requires the alignment tensors to be at the start of the parameter vector (unless the tensors are fixed).
    if opt_uses_align_data():
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Add the parameters.
            param_vector = param_vector + list(cdp.align_tensors[i].A_5D)

    # Monte Carlo simulation data structures.
    if sim_index != None:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs_sim[sim_index]

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha_sim[sim_index]
            beta = cdp.beta_sim[sim_index]
            gamma = cdp.gamma_sim[sim_index]

    # Normal data structures.
    else:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha
            beta = cdp.beta
            gamma = cdp.gamma

    # The probabilities (exclude that of state N).
    if cdp.model in ['2-domain', 'population']:
        param_vector = param_vector + probs[0:-1]

    # The Euler angles.
    if cdp.model == '2-domain':
        for i in range(cdp.N):
            param_vector.append(alpha[i])
            param_vector.append(beta[i])
            param_vector.append(gamma[i])

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        if not hasattr(cdp, 'paramagnetic_centre'):
            for i in range(3):
                param_vector.append(0.0)
        elif sim_index != None:
            if cdp.paramagnetic_centre_sim[sim_index] == None:
                for i in range(3):
                    param_vector.append(0.0)
            else:
                for i in range(3):
                    param_vector.append(cdp.paramagnetic_centre_sim[sim_index][i])
        else:
            for i in range(3):
                param_vector.append(cdp.paramagnetic_centre[i])

    # Convert all None values to zero (to avoid conversion to NaN).
    for i in range(len(param_vector)):
        if param_vector[i] == None:
            param_vector[i] = 0.0

    # Return a numpy arrary.
    return array(param_vector, float64)
예제 #15
0
def linear_constraints(data_types=None, scaling_matrix=None):
    """Function for setting up the linear constraint matrices A and b.

    Standard notation
    =================

    The N-state model constraints are::

        0 <= pc <= 1,

    where p is the probability and c corresponds to state c.


    Matrix notation
    ===============

    In the notation A.x >= b, where A is an matrix of coefficients, x is an array of parameter
    values, and b is a vector of scalars, these inequality constraints are::

        | 1  0  0 |                   |    0    |
        |         |                   |         |
        |-1  0  0 |                   |   -1    |
        |         |                   |         |
        | 0  1  0 |                   |    0    |
        |         |     |  p0  |      |         |
        | 0 -1  0 |     |      |      |   -1    |
        |         |  .  |  p1  |  >=  |         |
        | 0  0  1 |     |      |      |    0    |
        |         |     |  p2  |      |         |
        | 0  0 -1 |                   |   -1    |
        |         |                   |         |
        |-1 -1 -1 |                   |   -1    |
        |         |                   |         |
        | 1  1  1 |                   |    0    |

    This example is for a 4-state model, the last probability pn is not included as this
    parameter does not exist (because the sum of pc is equal to 1).  The Euler angle parameters
    have been excluded here but will be included in the returned A and b objects.  These
    parameters simply add columns of zero to the A matrix and have no effect on b.  The last two
    rows correspond to the inequality::

        0 <= pN <= 1.

    As::
                N-1
                \
        pN = 1 - >  pc,
                /__
                c=1

    then::

        -p1 - p2 - ... - p(N-1) >= -1,

         p1 + p2 + ... + p(N-1) >= 0.


    @keyword data_types:        The base data types used in the optimisation.  This list can
                                contain the elements 'rdc', 'pcs' or 'tensor'.
    @type data_types:           list of str
    @keyword scaling_matrix:    The diagonal scaling matrix.
    @type scaling_matrix:       numpy rank-2 square matrix
    @return:                    The matrices A and b.
    @rtype:                     tuple of len 2 of a numpy rank-2, size NxM matrix and numpy
                                rank-1, size N array
    """

    # Starting point of the populations.
    pop_start = 0
    if ('rdc' in data_types or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments.
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Add 5 parameters.
            pop_start += 5

    # Initialisation (0..j..m).
    A = []
    b = []
    zero_array = zeros(param_num(), float64)
    i = pop_start
    j = 0

    # Probability parameters.
    if cdp.model in ['2-domain', 'population']:
        # Loop over the prob parameters (N - 1, because the sum of pc is 1).
        for k in range(cdp.N - 1):
            # 0 <= pc <= 1.
            A.append(zero_array * 0.0)
            A.append(zero_array * 0.0)
            A[j][i] = 1.0
            A[j+1][i] = -1.0
            b.append(0.0)
            b.append(-1.0 / scaling_matrix[i, i])
            j = j + 2

            # Increment i.
            i = i + 1

        # Add the inequalities for pN.
        A.append(zero_array * 0.0)
        A.append(zero_array * 0.0)
        for i in range(pop_start, pop_start+cdp.N-1):
            A[-2][i] = -1.0
            A[-1][i] = 1.0
        b.append(-1.0 / scaling_matrix[i, i])
        b.append(0.0)

    # Convert to numpy data structures.
    A = array(A, float64)
    b = array(b, float64)

    # Return the constraint objects.
    return A, b
예제 #16
0
def disassemble_param_vector(param_vector=None, data_types=None, sim_index=None):
    """Disassemble the parameter vector and place the values into the relevant variables.

    For the 2-domain N-state model, the parameters are stored in the probability and Euler angle data structures.  For the population N-state model, only the probabilities are stored.  If RDCs are present and alignment tensors are optimised, then these are stored as well.

    @keyword data_types:    The base data types used in the optimisation.  This list can contain the elements 'rdc', 'pcs' or 'tensor'.
    @type data_types:       list of str
    @keyword param_vector:  The parameter vector returned from optimisation.
    @type param_vector:     numpy array
    @keyword sim_index:     The index of the simulation to optimise.  This should be None if normal optimisation is desired.
    @type sim_index:        None or int
    """

    # Test if the model is selected.
    if not hasattr(cdp, 'model') or not isinstance(cdp.model, str):
        raise RelaxNoModelError

    # Unpack and strip off the alignment tensor parameters.
    if ('rdc' in data_types or 'pcs' in data_types) and not align_tensor.all_tensors_fixed():
        # Loop over the alignments, adding the alignment tensor parameters to the tensor data container.
        tensor_num = 0
        for i in range(len(cdp.align_tensors)):
            # Skip non-optimised tensors.
            if not opt_uses_tensor(cdp.align_tensors[i]):
                continue

            # Normal tensors.
            if sim_index == None:
                cdp.align_tensors[i].set(param='Axx', value=param_vector[5*tensor_num])
                cdp.align_tensors[i].set(param='Ayy', value=param_vector[5*tensor_num+1])
                cdp.align_tensors[i].set(param='Axy', value=param_vector[5*tensor_num+2])
                cdp.align_tensors[i].set(param='Axz', value=param_vector[5*tensor_num+3])
                cdp.align_tensors[i].set(param='Ayz', value=param_vector[5*tensor_num+4])

            # Monte Carlo simulated tensors.
            else:
                cdp.align_tensors[i].set(param='Axx', value=param_vector[5*tensor_num], category='sim', sim_index=sim_index)
                cdp.align_tensors[i].set(param='Ayy', value=param_vector[5*tensor_num+1], category='sim', sim_index=sim_index)
                cdp.align_tensors[i].set(param='Axy', value=param_vector[5*tensor_num+2], category='sim', sim_index=sim_index)
                cdp.align_tensors[i].set(param='Axz', value=param_vector[5*tensor_num+3], category='sim', sim_index=sim_index)
                cdp.align_tensors[i].set(param='Ayz', value=param_vector[5*tensor_num+4], category='sim', sim_index=sim_index)

            # Increase the tensor number.
            tensor_num += 1

        # Create a new parameter vector without the tensors.
        param_vector = param_vector[5*tensor_num:]

    # Alias the Monte Carlo simulation data structures.
    if sim_index != None:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs_sim[sim_index]

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha_sim[sim_index]
            beta = cdp.beta_sim[sim_index]
            gamma = cdp.gamma_sim[sim_index]

    # Alias the normal data structures.
    else:
        # Populations.
        if cdp.model in ['2-domain', 'population']:
            probs = cdp.probs

        # Euler angles.
        if cdp.model == '2-domain':
            alpha = cdp.alpha
            beta = cdp.beta
            gamma = cdp.gamma

    # Set the probabilities for states 0 to N-1 in the aliased structures.
    if cdp.model in ['2-domain', 'population']:
        for i in range(cdp.N-1):
            probs[i] = param_vector[i]

        # The probability for state N.
        probs[-1] = 1 - sum(probs[0:-1])

    # Set the Euler angles in the aliased structures.
    if cdp.model == '2-domain':
        for i in range(cdp.N):
            alpha[i] = param_vector[cdp.N-1 + 3*i]
            beta[i] = param_vector[cdp.N-1 + 3*i + 1]
            gamma[i] = param_vector[cdp.N-1 + 3*i + 2]

    # The paramagnetic centre.
    if hasattr(cdp, 'paramag_centre_fixed') and not cdp.paramag_centre_fixed:
        # Create the structure if needed.
        if not hasattr(cdp, 'paramagnetic_centre'):
            cdp.paramagnetic_centre = zeros(3, float64)

        # The position.
        if sim_index == None:
            cdp.paramagnetic_centre[0] = param_vector[-3]
            cdp.paramagnetic_centre[1] = param_vector[-2]
            cdp.paramagnetic_centre[2] = param_vector[-1]

        # Monte Carlo simulated positions.
        else:
            if cdp.paramagnetic_centre_sim[sim_index] == None:
                cdp.paramagnetic_centre_sim[sim_index] = [None, None, None]
            cdp.paramagnetic_centre_sim[sim_index][0] = param_vector[-3]
            cdp.paramagnetic_centre_sim[sim_index][1] = param_vector[-2]
            cdp.paramagnetic_centre_sim[sim_index][2] = param_vector[-1]