def test(nave_model): model = Model(test_nave_model=nave_model) # cache objects from the model UB = matrix.sqr(model.crystal.get_A()) s0 = matrix.col(model.beam.get_s0()) es_radius = s0.length() # create the predictor and predict for reflection table from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(model.experiment) predictor.for_reflection_table(model.reflections, UB) # for every reflection, reconstruct relp rotated to the Ewald sphere (vector # r) and unrotated relp (vector q), calculate the angle between them and # compare with delpsical.rad from libtbx.test_utils import approx_equal for ref in model.reflections.rows(): r = matrix.col(ref["s1"]) - s0 q = UB * matrix.col(ref["miller_index"]) tst_radius = (s0 + q).length() sgn = -1 if tst_radius > es_radius else 1 delpsi = sgn * r.accute_angle(q) assert approx_equal(delpsi, ref["delpsical.rad"])
def check_experiment(experiment, reflections): # predict reflections in place from dials.algorithms.spot_prediction import StillsReflectionPredictor sp = StillsReflectionPredictor(experiment) UB = experiment.crystal.get_A() try: sp.for_reflection_table(reflections, UB) except RuntimeError: return False # calculate unweighted RMSDs x_obs, y_obs, _ = reflections['xyzobs.px.value'].parts() delpsi = reflections['delpsical.rad'] x_calc, y_calc, _ = reflections['xyzcal.px'].parts() # calculate residuals and assign columns x_resid = x_calc - x_obs x_resid2 = x_resid**2 y_resid = y_calc - y_obs y_resid2 = y_resid**2 delpsical2 = delpsi**2 r_x = flex.sum(x_resid2) r_y = flex.sum(y_resid2) r_z = flex.sum(delpsical2) # rmsd calculation n = len(reflections) rmsds = (sqrt(r_x / n), sqrt(r_y / n), sqrt(r_z / n)) # check positional RMSDs are within 5 pixels if rmsds[0] > 5: return False if rmsds[1] > 5: return False return True
def test_spherical_relps(): model = Model() # cache objects from the model UB = matrix.sqr(model.crystal.get_A()) s0 = matrix.col(model.beam.get_s0()) es_radius = s0.length() # create the predictor and predict for reflection table from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(model.experiment, spherical_relp=True) predictor.for_reflection_table(model.reflections, UB) # for every reflection, reconstruct relp centre q, calculate s1 according # to the formula in stills_prediction_nave3.pdf and compare from libtbx.test_utils import approx_equal for ref in model.reflections.rows(): q = UB * matrix.col(ref["miller_index"]) radicand = q.length_sq() + 2.0 * q.dot(s0) + s0.length_sq() assert radicand > 0.0 denom = sqrt(radicand) s1 = es_radius * (q + s0) / denom assert approx_equal(s1, ref["s1"])
def run(self): # cache objects from the model UB = self.crystal.get_U() * self.crystal.get_B() s0 = matrix.col(self.beam.get_s0()) es_radius = s0.length() # create the predictor and predict for reflection table from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(self.experiment) predictor.for_reflection_table(self.reflections, UB) # for every reflection, reconstruct relp rotated to the Ewald sphere (vector # r) and unrotated relp (vector q), calculate the angle between them and # compare with delpsical.rad from libtbx.test_utils import approx_equal for ref in self.reflections: r = matrix.col(ref['s1']) - s0 q = UB * matrix.col(ref['miller_index']) tst_radius = (s0 + q).length() sgn = -1 if tst_radius > es_radius else 1 delpsi = sgn*r.accute_angle(q) assert approx_equal(delpsi, ref['delpsical.rad']) print "OK"
class Predictor(object): def __init__(self, experiments): self._experiment = experiments[0] self.update() def update(self): """Build predictor objects for the current geometry of each Experiment""" self._predictor = StillsReflectionPredictor(self._experiment, spherical_relp=True) self._UB = matrix.sqr(self._experiment.crystal.get_U()) * matrix.sqr( self._experiment.crystal.get_B()) def predict(self, reflections): """ Predict for all reflections """ self._predictor.for_reflection_table(reflections, self._UB) return reflections
class Predictor(object): def __init__(self, experiments): self._experiment = experiments[0] self.update() def update(self): """Build predictor objects for the current geometry of each Experiment""" self._predictor = StillsReflectionPredictor(self._experiment, spherical_relp=True) self._UB = self._experiment.crystal.get_U() * self._experiment.crystal.get_B() def predict(self, reflections): """ Predict for all reflections """ self._predictor.for_reflection_table(reflections, self._UB) return reflections
def check_experiment(experiment, reflections): # predict reflections in place from dials.algorithms.spot_prediction import StillsReflectionPredictor sp = StillsReflectionPredictor(experiment) UB = experiment.crystal.get_U() * experiment.crystal.get_B() try: sp.for_reflection_table(reflections, UB) except RuntimeError: return False # calculate unweighted RMSDs x_obs, y_obs, _ = reflections['xyzobs.px.value'].parts() delpsi = reflections['delpsical.rad'] x_calc, y_calc, _ = reflections['xyzcal.px'].parts() # calculate residuals and assign columns x_resid = x_calc - x_obs x_resid2 = x_resid**2 y_resid = y_calc - y_obs y_resid2 = y_resid**2 delpsical2 = delpsi**2 r_x = flex.sum(x_resid2) r_y = flex.sum(y_resid2) r_z = flex.sum(delpsical2) # rmsd calculation n = len(reflections) rmsds = (sqrt(r_x / n), sqrt(r_y / n), sqrt(r_z / n)) # check positional RMSDs are within 5 pixels print rmsds if rmsds[0] > 5: return False if rmsds[1] > 5: return False return True
def spherical_relp(self): # cache objects from the model UB = self.crystal.get_U() * self.crystal.get_B() s0 = matrix.col(self.beam.get_s0()) es_radius = s0.length() # create the predictor and predict for reflection table from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(self.experiment, spherical_relp=True) predictor.for_reflection_table(self.reflections, UB) # for every reflection, reconstruct relp centre q, calculate s1 according # to the formula in stills_prediction_nave3.pdf and compare from libtbx.test_utils import approx_equal for ref in self.reflections: q = UB * matrix.col(ref['miller_index']) radicand = q.length_sq() + 2.0 * q.dot(s0) + s0.length_sq() assert radicand > 0.0 denom = sqrt(radicand) s1 = es_radius * (q + s0) / denom assert approx_equal(s1, ref['s1']) print "OK"
def get_predictions_accounting_for_centering(self, experiments, reflections, cb_op_to_primitive, **kwargs): # interface requires this function to set current_orientation # in the actual setting used for Miller index calculation detector = experiments[0].detector crystal = experiments[0].crystal if self.horizons_phil.integration.model == "user_supplied": lower_limit_domain_size = math.pow( crystal.get_unit_cell().volume(), 1. / 3. ) * self.horizons_phil.integration.mosaic.domain_size_lower_limit # default 10-unit cell block size minimum reasonable domain actual_used_domain_size = kwargs.get("domain_size_ang", lower_limit_domain_size) self.block_counter += 1 rot_mat = matrix.sqr( cb_op_to_primitive.c().r().as_double()).transpose() from cctbx.crystal_orientation import crystal_orientation, basis_type centered_orientation = crystal_orientation(crystal.get_A(), basis_type.reciprocal) self.current_orientation = centered_orientation self.current_cb_op_to_primitive = cb_op_to_primitive primitive_orientation = centered_orientation.change_basis(rot_mat) self.inputai.setOrientation(primitive_orientation) from cxi_user import pre_get_predictions if self.block_counter < 2: KLUDGE = self.horizons_phil.integration.mosaic.kludge1 # bugfix 1 of 2 for protocol 6, equation 2 self.inputai.setMosaicity(KLUDGE * self.inputai.getMosaicity()) oldbase = self.inputai.getBase() #print oldbase.xbeam, oldbase.ybeam newbeam = detector[0].get_beam_centre(experiments[0].beam.get_s0()) newdistance = -detector[0].get_beam_centre_lab( experiments[0].beam.get_s0())[2] from labelit.dptbx import Parameters base = Parameters( xbeam=newbeam[0], ybeam=newbeam[1], #oldbase.xbeam, ybeam = oldbase.ybeam, distance=newdistance, twotheta=0.0) self.inputai.setBase(base) self.inputai.setWavelength(experiments[0].beam.get_wavelength()) self.bp3_wrapper = pre_get_predictions( self.inputai, self.horizons_phil, raw_image=self.imagefiles.images[self.image_number], imageindex=self.frame_numbers[self.image_number], spotfinder=self.spotfinder, limiting_resolution=self.limiting_resolution, domain_size_ang=actual_used_domain_size, ) BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format( ) BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls() self.actual = actual_used_domain_size primitive_hkllist = BPhkllist #not sure if matrix needs to be transposed first for outputting HKL's???: self.hkllist = cb_op_to_primitive.inverse().apply( primitive_hkllist) if self.horizons_phil.integration.spot_prediction == "dials": from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(experiments[0]) Rcalc = flex.reflection_table.empty_standard(len(self.hkllist)) Rcalc['miller_index'] = self.hkllist predictor.for_reflection_table(Rcalc, crystal.get_A()) self.predicted = Rcalc['xyzcal.mm'] self.dials_spot_prediction = Rcalc self.dials_model = experiments elif self.horizons_phil.integration.spot_prediction == "ucbp3": self.predicted = BPpredicted self.inputai.setOrientation(centered_orientation) if self.inputai.active_areas != None: self.predicted, self.hkllist = self.inputai.active_areas( self.predicted, self.hkllist, self.pixel_size) if self.block_counter < 2: down = self.inputai.getMosaicity() / KLUDGE print "Readjusting mosaicity back down to ", down self.inputai.setMosaicity(down) return
def get_predictions_accounting_for_centering(self,experiments,reflections,cb_op_to_primitive,**kwargs): # interface requires this function to set current_orientation # in the actual setting used for Miller index calculation detector = experiments[0].detector crystal = experiments[0].crystal if self.horizons_phil.integration.model == "user_supplied": lower_limit_domain_size = math.pow( crystal.get_unit_cell().volume(), 1./3.)*self.horizons_phil.integration.mosaic.domain_size_lower_limit # default 10-unit cell block size minimum reasonable domain actual_used_domain_size = kwargs.get("domain_size_ang",lower_limit_domain_size) self.block_counter+=1 rot_mat = matrix.sqr(cb_op_to_primitive.c().r().as_double()).transpose() from cctbx.crystal_orientation import crystal_orientation, basis_type centered_orientation = crystal_orientation(crystal.get_A(),basis_type.reciprocal) self.current_orientation = centered_orientation self.current_cb_op_to_primitive = cb_op_to_primitive primitive_orientation = centered_orientation.change_basis(rot_mat) self.inputai.setOrientation(primitive_orientation) from cxi_user import pre_get_predictions if self.block_counter < 2: KLUDGE = self.horizons_phil.integration.mosaic.kludge1 # bugfix 1 of 2 for protocol 6, equation 2 self.inputai.setMosaicity(KLUDGE*self.inputai.getMosaicity()) oldbase = self.inputai.getBase() #print oldbase.xbeam, oldbase.ybeam newbeam = detector[0].get_beam_centre(experiments[0].beam.get_s0()) newdistance = -detector[0].get_beam_centre_lab(experiments[0].beam.get_s0())[2] from labelit.dptbx import Parameters base = Parameters(xbeam = newbeam[0], ybeam = newbeam[1], #oldbase.xbeam, ybeam = oldbase.ybeam, distance = newdistance, twotheta = 0.0) self.inputai.setBase(base) self.inputai.setWavelength(experiments[0].beam.get_wavelength()) self.bp3_wrapper = pre_get_predictions(self.inputai, self.horizons_phil, raw_image = self.imagefiles.images[self.image_number], imageindex = self.frame_numbers[self.image_number], spotfinder = self.spotfinder, limiting_resolution = self.limiting_resolution, domain_size_ang = actual_used_domain_size, ) BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format() BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls() self.actual = actual_used_domain_size primitive_hkllist = BPhkllist #not sure if matrix needs to be transposed first for outputting HKL's???: self.hkllist = cb_op_to_primitive.inverse().apply(primitive_hkllist) if self.horizons_phil.integration.spot_prediction == "dials": from dials.algorithms.spot_prediction import StillsReflectionPredictor predictor = StillsReflectionPredictor(experiments[0]) Rcalc = flex.reflection_table.empty_standard(len(self.hkllist)) Rcalc['miller_index'] = self.hkllist predictor.for_reflection_table(Rcalc, crystal.get_A()) self.predicted = Rcalc['xyzcal.mm'] self.dials_spot_prediction = Rcalc self.dials_model = experiments elif self.horizons_phil.integration.spot_prediction == "ucbp3": self.predicted = BPpredicted self.inputai.setOrientation(centered_orientation) if self.inputai.active_areas != None: self.predicted,self.hkllist = self.inputai.active_areas( self.predicted,self.hkllist,self.pixel_size) if self.block_counter < 2: down = self.inputai.getMosaicity()/KLUDGE print "Readjusting mosaicity back down to ",down self.inputai.setMosaicity(down) return
def extend_predictions(pdata, int_pickle_path, image_info, dmin=1.5, dump=False, detector_phil=None): """ Given a LABELIT format integration pickle, generate a new predictor for reflections extending to a higher resolution dmin matching the current unit cell, orientation, mosaicity and domain size. """ # image_info is an instance of ImageInfo img_path = image_info.img_path img_size = image_info.img_size pixel_size = image_info.pixel_size # pdata is the integration pickle object ori = pdata['current_orientation'][0] ucell = ori.unit_cell() sg = pdata['pointgroup'] cbop = pdata['current_cb_op_to_primitive'][0] xbeam = pdata['xbeam'] ybeam = pdata['ybeam'] wavelength = pdata['wavelength'] if 'effective_tiling' in pdata.keys(): tm_int = pdata['effective_tiling'] else: tiling = image_info.tiling_from_image(detector_phil=detector_phil) tm_int = tiling.effective_tiling_as_flex_int( reapply_peripheral_margin=True, encode_inactive_as_zeroes=True) xtal = symmetry(unit_cell=ucell, space_group="P1") indices = xtal.build_miller_set(anomalous_flag=True, d_min=dmin) params = parameters_bp3( indices=indices.indices(), orientation=ori, incident_beam=col((0., 0., -1.)), packed_tophat=col((1., 1., 0.)), detector_normal=col((0., 0., -1.)), detector_fast=col((0., 1., 0.)), # if buggy, try changing sign detector_slow=col((1., 0., 0.)), # if buggy, try changing sign pixel_size=col((pixel_size, pixel_size, 0.)), pixel_offset=col((0.5, 0.5, 0.0)), distance=pdata['distance'], detector_origin=col( (-ybeam, -xbeam, 0.))) # if buggy, try changing signs ucbp3 = use_case_bp3(parameters=params) # use the tiling manager above to construct the predictor parameters ucbp3.set_active_areas(tm_int) signal_penetration = 0.5 # from LG36 trial 94 params_2.phil ucbp3.set_sensor_model(thickness_mm=0.1, mu_rho=8.36644, signal_penetration=signal_penetration) # presume no subpixel corrections for now ucbp3.prescreen_indices(wavelength) ucbp3.set_orientation(ori) ucbp3.set_mosaicity(pdata['ML_half_mosaicity_deg'][0] * math.pi / 180) # radians ucbp3.set_domain_size(pdata['ML_domain_size_ang'][0]) bandpass = 1.E-3 wave_hi = wavelength * (1. - (bandpass / 2.)) wave_lo = wavelength * (1. + (bandpass / 2.)) ucbp3.set_bandpass(wave_hi, wave_lo) ucbp3.picture_fast_slow() # the full set of predictable reflections can now be accessed predicted = ucbp3.selected_predictions_labelit_format() hkllist = ucbp3.selected_hkls() # construct the experiment list and other dials backbone to be able to write predictions frame = construct_reflection_table_and_experiment_list( int_pickle_path, img_path, pixel_size, proceed_without_image=True) frame.assemble_experiments() frame.assemble_reflections() predictor = StillsReflectionPredictor(frame.experiment, dmin=1.5) Rcalc = flex.reflection_table.empty_standard(len(hkllist)) Rcalc['miller_index'] = hkllist expt_xtal = frame.experiment.crystal predictor.for_reflection_table(Rcalc, expt_xtal.get_A()) predicted = Rcalc['xyzcal.mm'] # # apply the active area filter # from iotbx.detectors.active_area_filter import active_area_filter # active_areas = list(tm.effective_tiling_as_flex_int()) # active_area_object = active_area_filter(active_areas) # aa_predicted, aa_hkllist = active_area_object(predicted, hkllist, 0.11) # extended_mapped_predictions = flex.vec2_double() # for i in range(len(aa_predicted)): # extended_mapped_predictions.append(aa_predicted[i][0:2]) # return predictions without re-applying an active area filter newpreds = flex.vec2_double() for i in range(len(predicted)): newpreds.append((predicted[i][0] / pixel_size, img_size - predicted[i][1] / pixel_size)) # finally, record new predictions as member data pdata['mapped_predictions_to_edge'] = newpreds pdata['indices_to_edge'] = hkllist if dump: newpath = int_pickle_path.split(".pickle")[0] + "_extended.pickle" easy_pickle.dump(newpath, pdata) else: return (hkllist, newpreds)