Beispiel #1
0
    def _match_full_turns(self, reflections):
        """Modify the calculated phi values so that they match the full rotation
        from zero taken from the the observations, rather than being modulo 2*pi."""

        x_obs, y_obs, phi_obs = reflections["xyzobs.mm.value"].parts()
        x_calc, y_calc, phi_calc = reflections["xyzcal.mm"].parts()
        resid = phi_calc - (flex.fmod_positive(phi_obs, TWO_PI))
        # ensure this is the smaller of two possibilities
        resid = flex.fmod_positive((resid + pi), TWO_PI) - pi
        phi_calc = phi_obs + resid
        reflections["xyzcal.mm"] = flex.vec3_double(x_calc, y_calc, phi_calc)

        # Update xyzcal.px with the correct z_px values in keeping with above
        for iexp, e in enumerate(self._experiments):
            sel = reflections["id"] == iexp
            x_px, y_px, z_px = reflections["xyzcal.px"].select(sel).parts()
            scan = e.scan
            if scan is not None:
                z_px = scan.get_array_index_from_angle(phi_calc.select(sel),
                                                       deg=False)
            else:
                # must be a still image, z centroid not meaningful
                z_px = phi_calc.select(sel)
            xyzcal_px = flex.vec3_double(x_px, y_px, z_px)
            reflections["xyzcal.px"].set_selected(sel, xyzcal_px)

        return reflections
Beispiel #2
0
  def _predict_core(self, reflections):
    """perform prediction for the specified reflections"""

    # update the reflection_predictor with the scan-independent part of the
    # current geometry
    self._reflection_predictor.update()

    # duck-typing for VaryingCrystalPredictionParameterisation. Only this
    # class has a compose(reflections) method. Sets ub_matrix (and caches
    # derivatives).
    try:
      self._prediction_parameterisation.compose(
          reflections)
    except AttributeError:
      pass

    # do prediction (updates reflection table in situ). Scan-varying prediction
    # is done automatically if the crystal has scan-points (assuming reflections
    # have ub_matrix set)

    self._reflection_predictor.predict(reflections)

    x_obs, y_obs, phi_obs = reflections['xyzobs.mm.value'].parts()
    x_calc, y_calc, phi_calc = reflections['xyzcal.mm'].parts()
    # do not wrap around multiples of 2*pi; keep the full rotation
    # from zero to differentiate repeat observations.
    resid = phi_calc - (flex.fmod_positive(phi_obs, TWO_PI))
    # ensure this is the smaller of two possibilities
    resid = flex.fmod_positive((resid + pi), TWO_PI) - pi
    phi_calc = phi_obs + resid
    # put back in the reflections
    reflections['xyzcal.mm'] = flex.vec3_double(x_calc, y_calc, phi_calc)

    # update xyzcal.px with the correct z_px values in keeping with above
    experiments = self._reflection_predictor._experiments
    for i, expt in enumerate(experiments):
      scan = expt.scan
      sel = (reflections['id'] == i)
      x_px, y_px, z_px = reflections['xyzcal.px'].select(sel).parts()
      if scan is not None:
        z_px = scan.get_array_index_from_angle(phi_calc.select(sel), deg=False)
      else:
        # must be a still image, z centroid not meaningful
        z_px = phi_calc.select(sel)
      xyzcal_px = flex.vec3_double(x_px, y_px, z_px)
      reflections['xyzcal.px'].set_selected(sel, xyzcal_px)

    # calculate residuals and assign columns
    reflections['x_resid'] = x_calc - x_obs
    reflections['x_resid2'] = reflections['x_resid']**2
    reflections['y_resid'] = y_calc - y_obs
    reflections['y_resid2'] = reflections['y_resid']**2
    reflections['phi_resid'] = phi_calc - phi_obs
    reflections['phi_resid2'] = reflections['phi_resid']**2

    return reflections
Beispiel #3
0
  def _predict_core(self, reflections, skip_derivatives=False):
    """perform prediction for the specified reflections"""

    # duck-typing for ScanVaryingPredictionParameterisation. Only this
    # class has a compose(reflections) method. Sets ub_matrix (and caches
    # derivatives).
    try:
      self._prediction_parameterisation.compose(
          reflections, skip_derivatives)
    except AttributeError:
      pass

    # do prediction (updates reflection table in situ). Scan-varying prediction
    # is done automatically if the crystal has scan-points (assuming reflections
    # have ub_matrix set)
    self._reflection_predictor(reflections)

    x_obs, y_obs, phi_obs = reflections['xyzobs.mm.value'].parts()
    x_calc, y_calc, phi_calc = reflections['xyzcal.mm'].parts()
    # do not wrap around multiples of 2*pi; keep the full rotation
    # from zero to differentiate repeat observations.
    resid = phi_calc - (flex.fmod_positive(phi_obs, TWO_PI))
    # ensure this is the smaller of two possibilities
    resid = flex.fmod_positive((resid + pi), TWO_PI) - pi
    phi_calc = phi_obs + resid
    # put back in the reflections
    reflections['xyzcal.mm'] = flex.vec3_double(x_calc, y_calc, phi_calc)

    # update xyzcal.px with the correct z_px values in keeping with above
    experiments = self._reflection_predictor._experiments
    for i, expt in enumerate(experiments):
      scan = expt.scan
      sel = (reflections['id'] == i)
      x_px, y_px, z_px = reflections['xyzcal.px'].select(sel).parts()
      if scan is not None:
        z_px = scan.get_array_index_from_angle(phi_calc.select(sel), deg=False)
      else:
        # must be a still image, z centroid not meaningful
        z_px = phi_calc.select(sel)
      xyzcal_px = flex.vec3_double(x_px, y_px, z_px)
      reflections['xyzcal.px'].set_selected(sel, xyzcal_px)

    # calculate residuals and assign columns
    reflections['x_resid'] = x_calc - x_obs
    reflections['x_resid2'] = reflections['x_resid']**2
    reflections['y_resid'] = y_calc - y_obs
    reflections['y_resid2'] = reflections['y_resid']**2
    reflections['phi_resid'] = phi_calc - phi_obs
    reflections['phi_resid2'] = reflections['phi_resid']**2

    return reflections