def generate_reflections(self):

    # Build a mock scan for a 3 degree sweep
    from dxtbx.model.scan import scan_factory
    sf = scan_factory()
    self.scan = sf.make_scan(image_range = (1,1),
                          exposure_times = 0.1,
                          oscillation = (0, 3.0),
                          epochs = range(1),
                          deg = True)
    sweep_range = self.scan.get_oscillation_range(deg=False)

    # Create a scans ExperimentList, only for generating reflections
    experiments = ExperimentList()
    experiments.append(Experiment(
          beam=self.beam, detector=self.detector, goniometer=self.gonio, scan=self.scan,
          crystal=self.crystal, imageset=None))

    # Create a ScansRayPredictor
    ray_predictor = ScansRayPredictor(experiments, sweep_range)

    # Generate rays - only to work out which hkls are predicted
    resolution = 2.0
    index_generator = IndexGenerator(self.crystal.get_unit_cell(),
                          space_group(space_group_symbols(1).hall()).type(),
                          resolution)
    indices = index_generator.to_array()
    rays = ray_predictor.predict(indices)

    # Make a standard reflection_table and copy in the ray data
    self.reflections = flex.reflection_table.empty_standard(len(rays))
    self.reflections.update(rays)

    return
def ref_gen_static(experiments):
  """Generate some reflections using the static predictor"""

  beam = experiments[0].beam
  crystal = experiments[0].crystal
  goniometer = experiments[0].goniometer
  detector = experiments[0].detector
  scan = experiments[0].scan

  # All indices to the detector max resolution
  dmin = detector.get_max_resolution(beam.get_s0())
  index_generator = IndexGenerator(crystal.get_unit_cell(),
                  space_group(space_group_symbols(1).hall()).type(), dmin)
  indices = index_generator.to_array()

  # Predict rays within the sweep range
  sweep_range = scan.get_oscillation_range(deg=False)
  ray_predictor = ScansRayPredictor(experiments, sweep_range)
  refs = ray_predictor.predict(indices)

  # Take only those rays that intersect the detector
  intersects = ray_intersection(detector, refs)
  refs = refs.select(intersects)

  # Make a reflection predictor and re-predict for these reflections. The
  # result is the same, but we gain also the flags and xyzcal.px columns
  ref_predictor = ExperimentsPredictor(experiments)
  refs['id'] = flex.int(len(refs), 0)
  refs = ref_predictor.predict(refs)

  return refs
def generate_reflections(experiments):

  from dials.algorithms.spot_prediction import IndexGenerator
  from dials.algorithms.refinement.prediction import \
    ScansRayPredictor, ExperimentsPredictor
  from dials.algorithms.spot_prediction import ray_intersection
  from cctbx.sgtbx import space_group, space_group_symbols
  from scitbx.array_family import flex

  detector = experiments[0].detector
  crystal = experiments[0].crystal

  # All indices in a 2.0 Angstrom sphere
  resolution = 2.0
  index_generator = IndexGenerator(crystal.get_unit_cell(),
                  space_group(space_group_symbols(1).hall()).type(), resolution)
  indices = index_generator.to_array()

  # Predict rays within the sweep range
  scan = experiments[0].scan
  sweep_range = scan.get_oscillation_range(deg=False)
  ray_predictor = ScansRayPredictor(experiments, sweep_range)
  obs_refs = ray_predictor.predict(indices)

  # Take only those rays that intersect the detector
  intersects = ray_intersection(detector, obs_refs)
  obs_refs = obs_refs.select(intersects)

  # Make a reflection predictor and re-predict for all these reflections. The
  # result is the same, but we gain also the flags and xyzcal.px columns
  ref_predictor = ExperimentsPredictor(experiments)
  obs_refs['id'] = flex.int(len(obs_refs), 0)
  obs_refs = ref_predictor.predict(obs_refs)

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

  # Invent some variances for the centroid positions of the simulated data
  im_width = 0.1 * pi / 180.
  px_size = detector[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)

  return obs_refs, ref_predictor
# All indices in a 2.0 Angstrom sphere for crystal1
resolution = 2.0
index_generator = IndexGenerator(crystal1.get_unit_cell(),
                space_group(space_group_symbols(1).hall()).type(), resolution)
indices1 = index_generator.to_array()

# All indices in a 2.0 Angstrom sphere for crystal2
resolution = 2.0
index_generator = IndexGenerator(crystal2.get_unit_cell(),
                space_group(space_group_symbols(1).hall()).type(), resolution)
indices2 = index_generator.to_array()

# Predict rays within the sweep range. Set experiment IDs
ray_predictor = ScansRayPredictor(experiments, sweep_range)
obs_refs1 = ray_predictor.predict(indices1, experiment_id=0)
obs_refs1['id'] = flex.int(len(obs_refs1), 0)
obs_refs2 = ray_predictor.predict(indices1, experiment_id=1)
obs_refs2['id'] = flex.int(len(obs_refs2), 1)

# Take only those rays that intersect the detector
intersects = ray_intersection(mydetector, obs_refs1)
obs_refs1 = obs_refs1.select(intersects)
intersects = ray_intersection(mydetector, obs_refs2)
obs_refs2 = obs_refs2.select(intersects)

# Make a reflection predictor and re-predict for all these reflections. The
# result is the same, but we gain also the flags and xyzcal.px columns
ref_predictor = ExperimentsPredictor(experiments)
obs_refs1 = ref_predictor.predict(obs_refs1)
obs_refs2 = ref_predictor.predict(obs_refs2)
def run(verbose = False):

  # Build models, with a larger crystal than default in order to get plenty of
  # reflections on the 'still' image
  overrides = """
  geometry.parameters.crystal.a.length.range=40 50;
  geometry.parameters.crystal.b.length.range=40 50;
  geometry.parameters.crystal.c.length.range=40 50;
  geometry.parameters.random_seed = 42"""

  master_phil = parse("""
      include scope dials.test.algorithms.refinement.geometry_phil
      """, process_includes=True)

  models = Extract(master_phil, overrides)

  mydetector = models.detector
  mygonio = models.goniometer
  mycrystal = models.crystal
  mybeam = models.beam

  # Build a mock scan for a 3 degree sweep
  from dxtbx.model.scan import scan_factory
  sf = scan_factory()
  myscan = sf.make_scan(image_range = (1,1),
                        exposure_times = 0.1,
                        oscillation = (0, 3.0),
                        epochs = range(1),
                        deg = True)
  sweep_range = myscan.get_oscillation_range(deg=False)

  # Create parameterisations of these models
  det_param = DetectorParameterisationSinglePanel(mydetector)
  s0_param = BeamParameterisation(mybeam, mygonio)
  xlo_param = CrystalOrientationParameterisation(mycrystal)
  xluc_param = CrystalUnitCellParameterisation(mycrystal)

  # Create a scans ExperimentList, only for generating reflections
  experiments = ExperimentList()
  experiments.append(Experiment(
        beam=mybeam, detector=mydetector, goniometer=mygonio, scan=myscan,
        crystal=mycrystal, imageset=None))

  # Create a stills ExperimentList
  stills_experiments = ExperimentList()
  stills_experiments.append(Experiment(
        beam=mybeam, detector=mydetector, crystal=mycrystal, imageset=None))

  # Generate rays - only to work out which hkls are predicted
  ray_predictor = ScansRayPredictor(experiments, sweep_range)
  resolution = 2.0
  index_generator = IndexGenerator(mycrystal.get_unit_cell(),
                        space_group(space_group_symbols(1).hall()).type(),
                        resolution)
  indices = index_generator.to_array()
  rays = ray_predictor.predict(indices)

  # Make a standard reflection_table and copy in the ray data
  reflections = flex.reflection_table.empty_standard(len(rays))
  reflections.update(rays)

  # Build a standard prediction parameterisation for the stills experiment to do
  # FD calculation (not used for its analytical gradients)
  pred_param = StillsPredictionParameterisation(stills_experiments,
                 detector_parameterisations = [det_param],
                 beam_parameterisations = [s0_param],
                 xl_orientation_parameterisations = [xlo_param],
                 xl_unit_cell_parameterisations = [xluc_param])

  # Make a managed SphericalRelpStillsReflectionPredictor reflection predictor
  # for the first (only) experiment
  ref_predictor = Predictor(stills_experiments)

  # Predict these reflections in place. Must do this ahead of calculating
  # the analytical gradients so quantities like s1 are correct
  ref_predictor.update()
  ref_predictor.predict(reflections)

  # calculate analytical gradients
  ag = AnalyticalGradients(stills_experiments,
                 detector_parameterisation=det_param,
                 beam_parameterisation=s0_param,
                 xl_orientation_parameterisation=xlo_param,
                 xl_unit_cell_parameterisation=xluc_param)
  an_grads = ag.get_beam_gradients(reflections)
  an_grads.update(ag.get_crystal_orientation_gradients(reflections))
  an_grads.update(ag.get_crystal_unit_cell_gradients(reflections))

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

  fd_grads = []
  p_names = pred_param.get_param_names()
  for i in range(len(deltas)):

    # save parameter value
    val = p_vals[i]

    # calc reverse state
    p_vals[i] -= deltas[i] / 2.
    pred_param.set_param_vals(p_vals)

    ref_predictor.update()
    ref_predictor.predict(reflections)

    x, y, _ = reflections['xyzcal.mm'].deep_copy().parts()
    delpsi = reflections['delpsical.rad'].deep_copy()
    s1 = reflections['s1'].deep_copy()
    rev_state = s1

    # calc forward state
    p_vals[i] += deltas[i]
    pred_param.set_param_vals(p_vals)

    ref_predictor.update()
    ref_predictor.predict(reflections)

    x, y, _ = reflections['xyzcal.mm'].deep_copy().parts()
    delpsi = reflections['delpsical.rad'].deep_copy()
    s1 = reflections['s1'].deep_copy()
    fwd_state = s1

    # reset parameter to saved value
    p_vals[i] = val

    # finite difference - currently for s1 only
    fd = (fwd_state - rev_state)
    inv_delta = 1. / deltas[i]
    s1_grads = fd * inv_delta

    # store gradients
    fd_grads.append({'name':p_names[i], 'ds1':s1_grads})

  # return to the initial state
  pred_param.set_param_vals(p_vals)

  for i, fd_grad in enumerate(fd_grads):

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

    print "d[s1]/dp for the first reflection"
    print 'finite diff', fd_grad['ds1'][0]
    try:
      an_grad = an_grads[fd_grad['name']]
    except KeyError:
      continue

    print 'checking analytical vs finite difference gradients for s1'
    for a, b in zip(fd_grad['ds1'], an_grad['ds1']):
      assert approx_equal(a, b)
    print 'OK'
#############################

# All indices in a 2.0 Angstrom sphere
resolution = 2.0
index_generator = IndexGenerator(mycrystal.get_unit_cell(),
                space_group(space_group_symbols(1).hall()).type(), resolution)
indices = index_generator.to_array()

sweep_range = myscan.get_oscillation_range(deg=False)
im_width = myscan.get_oscillation(deg=False)[1]
assert sweep_range == (0., pi)
assert approx_equal(im_width, 0.1 * pi / 180.)

# Predict rays within the sweep range
ray_predictor = ScansRayPredictor(experiments, sweep_range)
obs_refs = ray_predictor.predict(indices)

# Take only those rays that intersect the detector
intersects = ray_intersection(mydetector, obs_refs)
obs_refs = obs_refs.select(intersects)

# Make a reflection predictor and re-predict for all these reflections. The
# result is the same, but we gain also the flags and xyzcal.px columns
ref_predictor = ExperimentsPredictor(experiments)
obs_refs['id'] = flex.int(len(obs_refs), 0)
obs_refs = ref_predictor.predict(obs_refs)

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

# Invent some variances for the centroid positions of the simulated data
示例#7
0
def generate_reflections(experiments, xyzvar=(0.0, 0.0, 0.0)):
    """Generate synthetic reflection centroids using the supplied experiments,
    with normally-distributed errors applied the variances in xyzvar"""

    # check input
    if [e >= 0.0 for e in xyzvar].count(False) > 0:
        msg = "negative variance requested in " + str(xyzvar) + "!"
        raise RuntimeError(msg)

    refs = []
    for iexp, exp in enumerate(experiments):

        info("Generating reflections for experiment {0}".format(iexp))

        # All indices in a 1.5 Angstrom sphere
        resolution = 1.5
        index_generator = IndexGenerator(
            exp.crystal.get_unit_cell(),
            space_group(space_group_symbols(1).hall()).type(),
            resolution,
        )
        indices = index_generator.to_array()

        # Predict rays within the sweep range
        ray_predictor = ScansRayPredictor(
            experiments, exp.scan.get_oscillation_range(deg=False)
        )
        obs_refs = ray_predictor.predict(indices, experiment_id=iexp)

        info("Total number of reflections excited: {0}".format(len(obs_refs)))

        # Take only those rays that intersect the detector
        intersects = ray_intersection(exp.detector, obs_refs)
        obs_refs = obs_refs.select(intersects)
        obs_refs["id"] = flex.size_t(len(obs_refs), iexp)
        refs.append(obs_refs)

        info("Total number of impacts: {0}".format(len(obs_refs)))

    # Concatenate reflections
    obs_refs = reduce(lambda x, y: x.extend(y), refs)

    # Make a reflection predictor and re-predict for all these reflections. The
    # result is the same, but we gain also the flags and xyzcal.px columns
    ref_predictor = ExperimentsPredictor(experiments)
    obs_refs = ref_predictor.predict(obs_refs)

    # calculate (uncorrelated) errors to offset the centroids
    # this is safe as elts of xyzvar are already tested to be > 0
    sigX, sigY, sigZ = [sqrt(e) for e in xyzvar]
    shift = [
        (random.gauss(0, sigX), random.gauss(0, sigY), random.gauss(0, sigZ))
        for _ in xrange(len(obs_refs))
    ]
    shift = flex.vec3_double(shift)

    # Set 'observed' centroids from the predicted ones
    obs_refs["xyzobs.mm.value"] = obs_refs["xyzcal.mm"] + shift

    # Store variances for the centroid positions of the simulated data. If errors
    # are zero, invent some variances
    if tuple(xyzvar) == (0.0, 0.0, 0.0):
        im_width = exp.scan.get_oscillation()[1] * pi / 180.0
        px_size = exp.detector[0].get_pixel_size()
        xyzvar = (
            (px_size[0] / 2.0) ** 2,
            (px_size[1] / 2.0) ** 2,
            (im_width / 2.0) ** 2,
        )
    var_x = flex.double(len(obs_refs), xyzvar[0])
    var_y = flex.double(len(obs_refs), xyzvar[1])
    var_phi = flex.double(len(obs_refs), xyzvar[2])
    obs_refs["xyzobs.mm.variance"] = flex.vec3_double(var_x, var_y, var_phi)
    info("Total number of observations made: {0}".format(len(obs_refs)))

    return obs_refs
target_crystal = deepcopy(crystal)

#############################
# Generate some reflections #
#############################

# All indices in a 2.0 Angstrom sphere for crystal
resolution = 2.0
index_generator = IndexGenerator(crystal.get_unit_cell(),
                space_group(space_group_symbols(1).hall()).type(), resolution)
indices = index_generator.to_array()

# Build a ray predictor and predict rays close to the Ewald sphere by using
# the narrow rotation scan
ref_predictor = ScansRayPredictor(scans_experiments, sweep_range)
obs_refs = ref_predictor.predict(indices, experiment_id=0)

# Take only those rays that intersect the detector
intersects = ray_intersection(mydetector, obs_refs)
obs_refs = obs_refs.select(intersects)

# 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)
  #############################
  # Generate some reflections #
  #############################

  # All indices in a 2.0 Angstrom sphere
  resolution = 2.0
  index_generator = IndexGenerator(mycrystal.get_unit_cell(),
                  space_group(space_group_symbols(1).hall()).type(), resolution)
  indices = index_generator.to_array()

  # for the reflection predictor, it doesn't matter which experiment list is
  # passed, as the detector is not used
  ref_predictor = ScansRayPredictor(experiments_single_panel, sweep_range)

  # get two sets of identical reflections
  obs_refs = ref_predictor.predict(indices)
  obs_refs2 = ref_predictor.predict(indices)
  for r1, r2 in zip(obs_refs, obs_refs2):
    assert r1['s1'] == r2['s1']

  # get the panel intersections
  sel = ray_intersection(single_panel_detector, obs_refs)
  obs_refs = obs_refs.select(sel)
  sel = ray_intersection(multi_panel_detector, obs_refs2)
  obs_refs2 = obs_refs2.select(sel)
  assert len(obs_refs) == len(obs_refs2)

  # Set 'observed' centroids from the predicted ones
  obs_refs['xyzobs.mm.value'] = obs_refs['xyzcal.mm']
  obs_refs2['xyzobs.mm.value'] = obs_refs2['xyzcal.mm']
示例#10
0
def generate_reflections(experiments, xyzvar=(0., 0., 0.)):
  '''Generate synthetic reflection centroids using the supplied experiments,
  with normally-distributed errors applied the variances in xyzvar'''

  # check input
  if [e >= 0. for e in xyzvar].count(False) > 0:
    msg = "negative variance requested in " + str(xyzvar) + "!"
    raise RuntimeError(msg)

  refs = []
  for iexp, exp in enumerate(experiments):

    info("Generating reflections for experiment {0}".format(iexp))

    # All indices in a 1.5 Angstrom sphere
    resolution = 1.5
    index_generator = IndexGenerator(exp.crystal.get_unit_cell(),
                    space_group(space_group_symbols(1).hall()).type(), resolution)
    indices = index_generator.to_array()

    # Predict rays within the sweep range
    ray_predictor = ScansRayPredictor(experiments,
      exp.scan.get_oscillation_range(deg=False))
    obs_refs = ray_predictor.predict(indices, experiment_id=iexp)

    info("Total number of reflections excited: {0}".format(len(obs_refs)))

    # Take only those rays that intersect the detector
    intersects = ray_intersection(exp.detector, obs_refs)
    obs_refs = obs_refs.select(intersects)
    obs_refs['id'] = flex.size_t(len(obs_refs), iexp)
    refs.append(obs_refs)

    info("Total number of impacts: {0}".format(len(obs_refs)))

  # Concatenate reflections
  obs_refs = reduce(lambda x, y: x.extend(y), refs)

  # Make a reflection predictor and re-predict for all these reflections. The
  # result is the same, but we gain also the flags and xyzcal.px columns
  ref_predictor = ExperimentsPredictor(experiments)
  obs_refs = ref_predictor.predict(obs_refs)

  # calculate (uncorrelated) errors to offset the centroids
  # this is safe as elts of xyzvar are already tested to be > 0
  sigX, sigY, sigZ = [sqrt(e) for e in xyzvar]
  shift = [(random.gauss(0, sigX),
            random.gauss(0, sigY),
            random.gauss(0, sigZ)) for _ in xrange(len(obs_refs))]
  shift = flex.vec3_double(shift)

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

  # Store variances for the centroid positions of the simulated data. If errors
  # are zero, invent some variances
  if tuple(xyzvar) == (0., 0., 0.):
    im_width = exp.scan.get_oscillation()[1] * pi / 180.
    px_size = exp.detector[0].get_pixel_size()
    xyzvar = ((px_size[0] / 2.)**2, (px_size[1] / 2.)**2, (im_width / 2.)**2)
  var_x = flex.double(len(obs_refs), xyzvar[0])
  var_y = flex.double(len(obs_refs), xyzvar[1])
  var_phi = flex.double(len(obs_refs), xyzvar[2])
  obs_refs['xyzobs.mm.variance'] = flex.vec3_double(var_x, var_y, var_phi)
  info("Total number of observations made: {0}".format(len(obs_refs)))

  return obs_refs