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
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
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