Exemplo n.º 1
0
    def gradients(self):
        """A generator function to return the gradients dR/dp for all the restraints
        referring to a particular crystal's cell parameters. The return value is
        a list of sparse matrices, one for each of the 6 cell parameters being
        restrained. Each sparse matrix has as many columns as the crystal unit
        cell parameterisation has parameters, and as many rows as there are crystals
        being restrained. Gradients of zero are detected and not set in the sparse
        matrices to save memory."""

        for i, xlucp in enumerate(self._xlucp):
            B = xlucp.get_state()
            dB_dp = flex.mat3_double(xlucp.get_ds_dp())
            # Use C++ function for speed
            ccg = CalculateCellGradients(B, dB_dp)
            dRdp = []
            if self._sel[0]:
                dRdp.append(self._construct_grad_block(ccg.da_dp(), i))
            if self._sel[1]:
                dRdp.append(self._construct_grad_block(ccg.db_dp(), i))
            if self._sel[2]:
                dRdp.append(self._construct_grad_block(ccg.dc_dp(), i))
            if self._sel[3]:
                dRdp.append(self._construct_grad_block(ccg.daa_dp(), i))
            if self._sel[4]:
                dRdp.append(self._construct_grad_block(ccg.dbb_dp(), i))
            if self._sel[5]:
                dRdp.append(self._construct_grad_block(ccg.dcc_dp(), i))

            yield dRdp
Exemplo n.º 2
0
  def gradients(self):
    """A generator function to return the gradients dR/dp for all the restraints
    referring to a particular crystal's cell parameters. The return value is
    a list of sparse matrices, one for each of the 6 cell parameters being
    restrained. Each sparse matrix has as many columns as the crystal unit
    cell parameterisation has parameters, and as many rows as there are crystals
    being restrained. Gradients of zero are detected and not set in the sparse
    matrices to save memory."""

    for i, xlucp in enumerate(self._xlucp):
      B = xlucp.get_state()
      dB_dp = flex.mat3_double(xlucp.get_ds_dp())
      # Use C++ function for speed
      ccg = CalculateCellGradients(B, dB_dp)
      dRdp = []
      if self._sel[0]:
        dRdp.append(self._construct_grad_block(ccg.da_dp(), i))
      if self._sel[1]:
        dRdp.append(self._construct_grad_block(ccg.db_dp(), i))
      if self._sel[2]:
        dRdp.append(self._construct_grad_block(ccg.dc_dp(), i))
      if self._sel[3]:
        dRdp.append(self._construct_grad_block(ccg.daa_dp(), i))
      if self._sel[4]:
        dRdp.append(self._construct_grad_block(ccg.dbb_dp(), i))
      if self._sel[5]:
        dRdp.append(self._construct_grad_block(ccg.dcc_dp(), i))

      yield dRdp
Exemplo n.º 3
0
    def _calculate_uc_gradients(self, sel=[True] * 6):
        """Calculate gradients of the unit cell parameters with respect to
        each of the parameters of the crystal unit cell model parameterisation"""

        B = self._xlucp.get_state()
        dB_dp = flex.mat3_double(self._xlucp.get_ds_dp())

        # Use C++ function for speed
        ccg = CalculateCellGradients(B, dB_dp)

        nparam = len(dB_dp)
        da = list(ccg.da_dp()) if sel[0] else [0.0] * nparam
        db = list(ccg.db_dp()) if sel[1] else [0.0] * nparam
        dc = list(ccg.dc_dp()) if sel[2] else [0.0] * nparam
        daa = list(ccg.daa_dp()) if sel[3] else [0.0] * nparam
        dbb = list(ccg.dbb_dp()) if sel[4] else [0.0] * nparam
        dcc = list(ccg.dcc_dp()) if sel[5] else [0.0] * nparam

        return (da, db, dc, daa, dbb, dcc)
Exemplo n.º 4
0
  def _calculate_uc_gradients(self, sel=[True]*6):
    '''Calculate gradients of the unit cell parameters with respect to
    each of the parameters of the crystal unit cell model parameterisation'''

    B = self._xlucp.get_state()
    dB_dp = flex.mat3_double(self._xlucp.get_ds_dp())

    # Use C++ function for speed
    ccg = CalculateCellGradients(B, dB_dp)

    nparam = len(dB_dp)
    da = list(ccg.da_dp()) if sel[0] else [0.0] * nparam
    db = list(ccg.db_dp()) if sel[1] else [0.0] * nparam
    dc = list(ccg.dc_dp()) if sel[2] else [0.0] * nparam
    daa = list(ccg.daa_dp()) if sel[3] else [0.0] * nparam
    dbb = list(ccg.dbb_dp()) if sel[4] else [0.0] * nparam
    dcc = list(ccg.dcc_dp()) if sel[5] else [0.0] * nparam

    return (da, db, dc, daa, dbb, dcc)
Exemplo n.º 5
0
    def __init__(self, model_parameterisations, sigma):
        """model_parameterisations is a list of CrystalUnitCellParameterisations

        sigma is a sequence of 6 elements giving the 'sigma' for each of the
        unit cell parameters, from which weights for the residuals will be
        calculated. Values of zero in sigma will remove the restraint for the
        cell parameter at that position"""

        self._xlucp = model_parameterisations
        self._nxls = len(model_parameterisations)

        # common factors used in gradient calculations
        self._meangradfac = 1.0 / self._nxls
        self._gradfac = 1.0 - self._meangradfac

        self._weights = []

        # initially want to calculate all gradients
        self._sel = [True] * 6

        # identify any cell dimensions constrained to be equal. If any are and a
        # restraint has been requested for that cell dimension, remove the restraint
        # for all crystals and warn in the log
        msg = ("Unit cell similarity restraints were requested for both the "
               "{0} and {1} dimensions, however for the crystal in experiment "
               "{2} these are constrained to be equal. Only the strongest "
               "of these restraints will be retained for all crystals in "
               "the restrained group.")
        for ixl, xlucp in enumerate(self._xlucp):
            B = xlucp.get_state()
            dB_dp = flex.mat3_double(xlucp.get_ds_dp())
            ccg = CalculateCellGradients(B, dB_dp)
            grads = [
                ccg.da_dp(),
                ccg.db_dp(),
                ccg.dc_dp(),
                ccg.daa_dp(),
                ccg.dbb_dp(),
                ccg.dcc_dp(),
            ]
            a, b, c, aa, bb, cc = xlucp.get_model().get_unit_cell().parameters(
            )
            if abs(a - b) < 1e-10:
                grad_diff = [
                    abs(e1 - e2) for (e1, e2) in zip(grads[0], grads[1])
                ]
                if max(grad_diff) < 1e-10:
                    # a and b are equal for this crystal, therefore keep only the
                    # strongest requested restraint
                    if sigma[0] > 0.0 and sigma[1] > 0.0:
                        logger.debug(
                            msg.format("a", "b",
                                       xlucp.get_experiment_ids()[0]))
                        strong, weak = sorted([sigma[0], sigma[1]])
                        sigma[0] = strong
                        sigma[1] = 0.0
            if abs(a - c) < 1e-10:
                grad_diff = [
                    abs(e1 - e2) for (e1, e2) in zip(grads[0], grads[2])
                ]
                if max(grad_diff) < 1e-10:
                    # a and c are equal for this crystal, therefore keep only the
                    # strongest requested restraint
                    if sigma[0] > 0.0 and sigma[2] > 0.0:
                        logger.debug(
                            msg.format("a", "c",
                                       xlucp.get_experiment_ids()[0]))
                        strong, weak = sorted([sigma[0], sigma[2]])
                        sigma[0] = strong
                        sigma[2] = 0.0
            if abs(b - c) < 1e-10:
                grad_diff = [
                    abs(e1 - e2) for (e1, e2) in zip(grads[1], grads[2])
                ]
                if max(grad_diff) < 1e-10:
                    # b and c are equal for this crystal, therefore keep only the
                    # strongest requested restraint
                    if sigma[1] > 0.0 and sigma[2] > 0.0:
                        logger.debug(
                            msg.format("b", "c",
                                       xlucp.get_experiment_ids()[0]))
                        strong, weak = sorted([sigma[1], sigma[2]])
                        sigma[1] = strong
                        sigma[2] = 0.0

            # A gradient of zero indicates that cell parameter is constrained and thus
            # to be ignored in restraints
            # _sigma = []
            msg = (
                "Unit cell similarity restraints were requested for the {0} "
                "parameter, however for the crystal in experiment {1}, {0} is "
                "constrained. This restraint will be removed for all crystals in "
                "the restrained group.")
            for i, (grad, pname) in enumerate(
                    zip(grads, ["a", "b", "c", "alpha", "beta", "gamma"])):
                tst = (abs(g) <= 1.0e-10 for g in grad)
                if all(tst):
                    # this parameter is constrained, so remove any requested restraints
                    # at this position
                    if sigma[i] > 0.0:
                        logger.debug(
                            msg.format(pname,
                                       xlucp.get_experiment_ids()[0]))
                        sigma[i] = 0.0

        # set the selection for gradient calculations to the unconstrained parameters
        self._sel = [s > 0.0 for s in sigma]

        self.nrestraints_per_cell = self._sel.count(True)

        # repeat the weights for each unit cell being restrained
        weights = [1.0 / s**2 for s in sigma if s > 0.0]
        weights = [flex.double(self._nxls, w) for w in weights]
        self._weights = weights[0]
        for w in weights[1:]:
            self._weights.extend(w)