コード例 #1
0
  def run_spherical_relp_stills_pred_param(self, verbose=True):

    if verbose:
      print 'Testing derivatives for SphericalRelpStillsPredictionParameterisation'
      print '====================================================================='

    # Build a prediction parameterisation for the stills experiment
    pred_param = SphericalRelpStillsPredictionParameterisation(
                   self.stills_experiments,
                   detector_parameterisations = [self.det_param],
                   beam_parameterisations = [self.s0_param],
                   xl_orientation_parameterisations = [self.xlo_param],
                   xl_unit_cell_parameterisations = [self.xluc_param])

    # Predict the reflections in place. Must do this ahead of calculating
    # the analytical gradients so quantities like s1 are correct
    from dials.algorithms.refinement.prediction import ExperimentsPredictor
    ref_predictor = ExperimentsPredictor(self.stills_experiments,
      spherical_relp=True)
    ref_predictor.update()
    ref_predictor.predict(self.reflections)

    # get analytical gradients
    an_grads = pred_param.get_gradients(self.reflections)

    fd_grads = self.get_fd_gradients(pred_param, ref_predictor)

    # compare FD with analytical calculations
    for i, (an_grad, fd_grad) in enumerate(zip(an_grads, fd_grads)):
      if verbose: print "\nParameter {0}: {1}". format(i,  fd_grad['name'])
      for idx, name in enumerate(["dX_dp", "dY_dp", "dDeltaPsi_dp"]):
        if verbose: print name
        for a, b in zip(an_grad[name], fd_grad[name]):
          if name == 'dDeltaPsi_dp':
            # DeltaPsi errors are much worse than X, Y errors!
            # FIXME, look into this further
            assert approx_equal(a,b, eps=5e-3)
          else:
            assert approx_equal(a,b, eps=5e-6)
        if verbose: print "OK"
    if verbose: print
コード例 #2
0
pred_param.compose(reflections)
an_grads = pred_param.get_gradients(reflections)

# get finite difference gradients
p_vals = pred_param.get_param_vals()
deltas = [1.e-7] * len(p_vals)

for i in range(len(deltas)):

  val = p_vals[i]

  p_vals[i] -= deltas[i] / 2.
  pred_param.set_param_vals(p_vals)
  pred_param.compose(reflections)

  ref_predictor.update()
  ref_predictor.predict(reflections)

  rev_state = reflections['xyzcal.mm'].deep_copy()

  p_vals[i] += deltas[i]
  pred_param.set_param_vals(p_vals)
  pred_param.compose(reflections)

  ref_predictor.update()
  ref_predictor.predict(reflections)

  fwd_state = reflections['xyzcal.mm'].deep_copy()
  p_vals[i] = val

  fd = (fwd_state - rev_state)
コード例 #3
0
  def run_stills_pred_param(self, verbose = False):

    if verbose:
      print 'Testing derivatives for StillsPredictionParameterisation'
      print '========================================================'

    # Build a prediction parameterisation for the stills experiment
    pred_param = StillsPredictionParameterisation(self.stills_experiments,
                   detector_parameterisations = [self.det_param],
                   beam_parameterisations = [self.s0_param],
                   xl_orientation_parameterisations = [self.xlo_param],
                   xl_unit_cell_parameterisations = [self.xluc_param])

    # Predict the reflections in place. Must do this ahead of calculating
    # the analytical gradients so quantities like s1 are correct
    from dials.algorithms.refinement.prediction import ExperimentsPredictor
    ref_predictor = ExperimentsPredictor(self.stills_experiments)
    ref_predictor.update()
    ref_predictor.predict(self.reflections)

    # get analytical gradients
    an_grads = pred_param.get_gradients(self.reflections)

    fd_grads = self.get_fd_gradients(pred_param, ref_predictor)

    for i, (an_grad, fd_grad) in enumerate(zip(an_grads, fd_grads)):

      # compare FD with analytical calculations
      if verbose: print "\nParameter {0}: {1}". format(i,  fd_grad['name'])

      for idx, name in enumerate(["dX_dp", "dY_dp", "dDeltaPsi_dp"]):
        if verbose: print name
        a = fd_grad[name]
        b = an_grad[name]

        abs_error = a - b
        denom = a + b

        fns = five_number_summary(abs_error)
        if verbose: print ("  summary of absolute errors: %9.6f %9.6f %9.6f " + \
          "%9.6f %9.6f") % fns
        assert flex.max(flex.abs(abs_error)) < 0.0003
        # largest absolute error found to be about 0.00025 for dY/dp of
        # Crystal0g_param_3. Reject outlying absolute errors and test again.
        iqr = fns[3] - fns[1]

        # skip further stats on errors with an iqr of near zero, e.g. dDeltaPsi_dp
        # for detector parameters, which are all equal to zero
        if iqr < 1.e-10:
          continue

        sel1 = abs_error < fns[3] + 1.5 * iqr
        sel2 = abs_error > fns[1] - 1.5 * iqr
        sel = sel1 & sel2
        tst = flex.max_index(flex.abs(abs_error.select(sel)))
        tst_val = abs_error.select(sel)[tst]
        n_outliers = sel.count(False)
        if verbose: print ("  {0} outliers rejected, leaving greatest " + \
          "absolute error: {1:9.6f}").format(n_outliers, tst_val)
        # largest absolute error now 0.000086 for dX/dp of Beam0Mu2
        assert abs(tst_val) < 0.00009

        # Completely skip parameters with FD gradients all zero (e.g. gradients of
        # DeltaPsi for detector parameters)
        sel1 = flex.abs(a) < 1.e-10
        if sel1.all_eq(True):
          continue

        # otherwise calculate normalised errors, by dividing absolute errors by
        # the IQR (more stable than relative error calculation)
        norm_error = abs_error / iqr
        fns = five_number_summary(norm_error)
        if verbose: print ("  summary of normalised errors: %9.6f %9.6f %9.6f " + \
          "%9.6f %9.6f") % fns
        # largest normalised error found to be about 25.7 for dY/dp of
        # Crystal0g_param_3.
        try:
          assert flex.max(flex.abs(norm_error)) < 30
        except AssertionError as e:
          e.args += ("extreme normalised error value: {0}".format(
                     flex.max(flex.abs(norm_error))),)
          raise e

        # Reject outlying normalised errors and test again
        iqr = fns[3] - fns[1]
        if iqr > 0.:
          sel1 = norm_error < fns[3] + 1.5 * iqr
          sel2 = norm_error > fns[1] - 1.5 * iqr
          sel = sel1 & sel2
          tst = flex.max_index(flex.abs(norm_error.select(sel)))
          tst_val = norm_error.select(sel)[tst]
          n_outliers = sel.count(False)

          # most outliers found for for dY/dp of Crystal0g_param_3 (which had
          # largest errors, so no surprise there).
          try:
            assert n_outliers < 250
          except AssertionError as e:
            e.args += ("too many outliers rejected: {0}".format(n_outliers),)
            raise e

          if verbose: print ("  {0} outliers rejected, leaving greatest " + \
            "normalised error: {1:9.6f}").format(n_outliers, tst_val)
          # largest normalied error now about -4. for dX/dp of Detector0Tau1
          assert abs(tst_val) < 4.5
    if verbose: print

    return
コード例 #4
0
# Add in flags and ID columns by copying into standard reflection table
tmp = flex.reflection_table.empty_standard(len(obs_refs))
tmp.update(obs_refs)
obs_refs = tmp

# Invent some variances for the centroid positions of the simulated data
im_width = 0.1 * pi / 180.
px_size = mydetector[0].get_pixel_size()
var_x = flex.double(len(obs_refs), (px_size[0] / 2.)**2)
var_y = flex.double(len(obs_refs), (px_size[1] / 2.)**2)
var_phi = flex.double(len(obs_refs), (im_width / 2.)**2)
obs_refs['xyzobs.mm.variance'] = flex.vec3_double(var_x, var_y, var_phi)

# Re-predict using the stills reflection predictor
stills_ref_predictor = ExperimentsPredictor(stills_experiments)
stills_ref_predictor.update()
obs_refs_stills = stills_ref_predictor.predict(obs_refs)

# Set 'observed' centroids from the predicted ones
obs_refs_stills['xyzobs.mm.value'] = obs_refs_stills['xyzcal.mm']

###############################
# Undo known parameter shifts #
###############################

xlo_param.set_param_vals(xlo_p_vals[0])
xluc_param.set_param_vals(xluc_p_vals[0])

# make a refiner
from dials.algorithms.refinement.refiner import phil_scope
from libtbx.phil import parse