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(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 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 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"
def predict_spots_from_rayonix_crystal_model(self, experiments, observed): """ Reads in the indexed rayonix model, predict spots using the crystal model on the jungfrau detector""" pass # Make sure experimental model for rayonix is supplied. Also the experimental geometry of the jungfrau is supplied assert self.params.LS49.path_to_rayonix_crystal_models is not None, 'Rayonix crystal model path is empty. Needs to be specified' assert self.params.LS49.path_to_jungfrau_detector_model is not None, 'Jungfrau_detector model path is empty. Needs to be specified' ts = self.tag.split( '_' )[-1] # Assuming jungfrau cbfs are names as 'jungfrauhit_20180501133315870' # Load rayonix experimental model rayonix_fname = os.path.join( self.params.LS49.path_to_rayonix_crystal_models, 'idx-%s_integrated_experiments.json' % ts) rayonix_expt = ExperimentListFactory.from_json_file(rayonix_fname, check_format=False) jungfrau_det = ExperimentListFactory.from_json_file( self.params.LS49.path_to_jungfrau_detector_model, check_format=False) # Reset stuff here # Should have # a. Jungfrau detector geometry # b. Rayonix indexed crystal model from dials.algorithms.refinement.prediction.managed_predictors import ExperimentsPredictorFactory from dials.algorithms.indexing import index_reflections experiments[0].detector = jungfrau_det[0].detector experiments[0].crystal = rayonix_expt[0].crystal if False: observed['id'] = flex.int(len(observed), -1) observed['imageset_id'] = flex.int(len(observed), 0) observed.centroid_px_to_mm(experiments[0].detector, experiments[0].scan) observed.map_centroids_to_reciprocal_space( experiments[0].detector, experiments[0].beam, experiments[0].goniometer) index_reflections(observed, experiments) ref_predictor = ExperimentsPredictorFactory.from_experiments( experiments) ref_predictor(observed) observed['id'] = flex.int(len(observed), 0) from libtbx.easy_pickle import dump dump('my_observed_prediction_%s.pickle' % self.tag, observed) dumper = ExperimentListDumper(experiments) dumper.as_json('my_observed_prediction_%s.json' % self.tag) predictor = StillsReflectionPredictor(experiments[0]) ubx = predictor.for_ub(experiments[0].crystal.get_A()) ubx['id'] = flex.int(len(ubx), 0) n_predictions = len(ubx) n_observed = len(observed) if len(observed) > 3 and len(ubx) >= len(observed): from libtbx.easy_pickle import dump dump('my_prediction_%s.pickle' % self.tag, ubx) dumper = ExperimentListDumper(experiments) dumper.as_json('my_prediction_%s.json' % self.tag) #from IPython import embed; embed(); exit() exit()
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 __init__( self, experiment, dmin=None, dmax=None, margin=1, force_static=False, padding=0 ): """ Initialise a predictor for each experiment. :param experiment: The experiment to predict for :param dmin: The maximum resolution :param dmax: The minimum resolution :param margin: The margin of hkl to predict :param force_static: force scan varying prediction to be static """ from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor from dials.algorithms.spot_prediction import ScanVaryingReflectionPredictor from dials.algorithms.spot_prediction import StillsReflectionPredictor from dxtbx.imageset import ImageSweep from dials.array_family import flex class Predictor(object): def __init__(self, name, func): self.name = name self.func = func def __call__(self): result = self.func() if dmax is not None: assert dmax > 0 result.compute_d_single(experiment) mask = result["d"] > dmax result.del_selected(mask) return result # Check prediction to maximum resolution is possible wl = experiment.beam.get_wavelength() if dmin is not None and dmin < 0.5 * wl: raise Sorry( "Prediction at d_min of {0} is not possible " "with wavelength {1}".format(dmin, wl) ) # Select the predictor class if isinstance(experiment.imageset, ImageSweep): xl_nsp = experiment.crystal.num_scan_points bm_nsp = experiment.beam.num_scan_points gn_nsp = experiment.goniometer.num_scan_points nim = experiment.scan.get_num_images() sv_compatible = (xl_nsp == nim + 1) or (bm_nsp == nim + 1) if not force_static and sv_compatible: predictor = ScanVaryingReflectionPredictor( experiment, dmin=dmin, margin=margin, padding=padding ) if bm_nsp == 0 and gn_nsp == 0: # Only varying crystal A = [ experiment.crystal.get_A_at_scan_point(i) for i in range(experiment.crystal.num_scan_points) ] predict = Predictor( "scan varying crystal prediction", lambda: predictor.for_ub(flex.mat3_double(A)), ) else: # Any allowed model may vary if xl_nsp == nim + 1: A = [ experiment.crystal.get_A_at_scan_point(i) for i in range(experiment.crystal.num_scan_points) ] else: A = [experiment.crystal.get_A() for i in range(nim + 1)] if bm_nsp == nim + 1: s0 = [ experiment.beam.get_s0_at_scan_point(i) for i in range(experiment.beam.num_scan_points) ] else: s0 = [experiment.beam.get_s0() for i in range(nim + 1)] if gn_nsp == nim + 1: S = [ experiment.goniometer.get_setting_rotation_at_scan_point(i) for i in range(experiment.goniometer.num_scan_points) ] else: S = [ experiment.goniometer.get_setting_rotation() for i in range(nim + 1) ] predict = Predictor( "scan varying model prediction", lambda: predictor.for_varying_models( flex.mat3_double(A), flex.vec3_double(s0), flex.mat3_double(S), ), ) else: predictor = ScanStaticReflectionPredictor( experiment, dmin=dmin, padding=padding ) # Choose index generation method based on number of images # https://github.com/dials/dials/issues/585 if experiment.scan.get_num_images() > 50: predict_method = predictor.for_ub_old_index_generator else: predict_method = predictor.for_ub predict = Predictor( "scan static prediction", lambda: predict_method(experiment.crystal.get_A()), ) else: predictor = StillsReflectionPredictor(experiment, dmin=dmin) predict = Predictor( "stills prediction", lambda: predictor.for_ub(experiment.crystal.get_A()), ) # Create and add the predictor class self._predict = predict
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 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 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)
def __init__(self, experiment, dmin=None, dmax=None, margin=1, force_static=False, padding=0): ''' Initialise a predictor for each experiment. :param experiment: The experiment to predict for :param dmin: The maximum resolution :param dmax: The minimum resolution :param margin: The margin of hkl to predict :param force_static: force scan varying prediction to be static ''' from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor from dials.algorithms.spot_prediction import ScanVaryingReflectionPredictor from dials.algorithms.spot_prediction import StillsReflectionPredictor from dxtbx.imageset import ImageSweep from dials.array_family import flex class Predictor(object): def __init__(self, name, func): self.name = name self.func = func def __call__(self): result = self.func() if dmax is not None: assert (dmax > 0) result.compute_d_single(experiment) mask = result['d'] > dmax result.del_selected(mask) return result # Check prediction to maximum resolution is possible wl = experiment.beam.get_wavelength() if dmin is not None and dmin < 0.5 * wl: raise Sorry("Prediction at d_min of {0} is not possible " "with wavelength {1}".format(dmin, wl)) # Select the predictor class if isinstance(experiment.imageset, ImageSweep): nsp = experiment.crystal.num_scan_points nim = experiment.scan.get_num_images() if not force_static and nsp == nim + 1: predictor = ScanVaryingReflectionPredictor(experiment, dmin=dmin, margin=margin, padding=padding) A = [ experiment.crystal.get_A_at_scan_point(i) for i in range(experiment.crystal.num_scan_points) ] predict = Predictor( "scan varying prediction", lambda: predictor.for_ub(flex.mat3_double(A))) else: predictor = ScanStaticReflectionPredictor(experiment, dmin=dmin, padding=padding) predict = Predictor( "scan static prediction", lambda: predictor.for_ub(experiment.crystal.get_A())) else: predictor = StillsReflectionPredictor(experiment, dmin=dmin) predict = Predictor( "stills prediction", lambda: predictor.for_ub(experiment.crystal.get_A())) # Create and add the predictor class self._predict = predict