Example #1
0
def candidate_orientation_matrices(basis_vectors, max_combinations=None):

    # select unique combinations of input vectors to test
    # the order of combinations is such that combinations comprising vectors
    # nearer the beginning of the input list will appear before combinations
    # comprising vectors towards the end of the list
    n = len(basis_vectors)
    # hardcoded limit on number of vectors, fixes issue #72
    # https://github.com/dials/dials/issues/72
    n = min(n, 100)
    basis_vectors = basis_vectors[:n]
    combinations = flex.vec3_int(flex.nested_loop((n, n, n)))
    combinations = combinations.select(
        flex.sort_permutation(combinations.as_vec3_double().norms()))

    # select only those combinations where j > i and k > j
    i, j, k = combinations.as_vec3_double().parts()
    sel = flex.bool(len(combinations), True)
    sel &= j > i
    sel &= k > j
    combinations = combinations.select(sel)

    if max_combinations is not None and max_combinations < len(combinations):
        combinations = combinations[:max_combinations]

    half_pi = 0.5 * math.pi
    min_angle = 20 / 180 * math.pi  # 20 degrees, arbitrary cutoff
    for i, j, k in combinations:
        a = basis_vectors[i]
        b = basis_vectors[j]
        angle = a.angle(b)
        if angle < min_angle or (math.pi - angle) < min_angle:
            continue
        a_cross_b = a.cross(b)
        gamma = a.angle(b)
        if gamma < half_pi:
            # all angles obtuse if possible please
            b = -b
            a_cross_b = -a_cross_b
        c = basis_vectors[k]
        if abs(half_pi - a_cross_b.angle(c)) < min_angle:
            continue
        alpha = b.angle(c, deg=True)
        if alpha < half_pi:
            c = -c
        if a_cross_b.dot(c) < 0:
            # we want right-handed basis set, therefore invert all vectors
            a = -a
            b = -b
            c = -c
        model = Crystal(a, b, c, space_group_symbol="P 1")
        uc = model.get_unit_cell()
        cb_op_to_niggli = uc.change_of_basis_op_to_niggli_cell()
        model = model.change_basis(cb_op_to_niggli)

        uc = model.get_unit_cell()
        params = uc.parameters()
        if uc.volume() > (params[0] * params[1] * params[2] / 100):
            # unit cell volume cutoff from labelit 2004 paper
            yield model
def get_indexing_offset_correlation_coefficients(
    reflections, crystal, grid_search_scope, d_min=None, d_max=None, map_to_asu=False
):

    from copy import deepcopy
    from dials.array_family import flex

    space_group = crystal.get_space_group()
    unit_cell = crystal.get_unit_cell()
    from cctbx.crystal import symmetry as crystal_symmetry

    cs = crystal_symmetry(unit_cell, space_group.type().lookup_symbol())

    from cctbx.miller import set as miller_set

    data = reflections["intensity.sum.value"] / flex.sqrt(reflections["intensity.sum.variance"])

    ccs = flex.double()
    offsets = flex.vec3_int()
    nref = flex.size_t()

    original_miller_indices = reflections["miller_index"]
    ms = miller_set(cs, original_miller_indices)
    ms = ms.array(data)

    if d_min is not None or d_max is not None:
        ms = ms.resolution_filter(d_min=d_min, d_max=d_max)

    if map_to_asu:
        ms = ms.map_to_asu()

    g = grid_search_scope

    for h in range(-g, g + 1):
        for k in range(-g, g + 1):
            for l in range(-g, g + 1):
                for smx in ["-x,-y,-z"]:
                    # reindexed = deepcopy(reflections)
                    # hkl offset doubled as equivalent of h0 + 1, hI - 1
                    miller_indices = offset_miller_indices(ms.indices(), (2 * h, 2 * k, 2 * l))
                    reindexed_miller_indices = sgtbx.change_of_basis_op(smx).apply(miller_indices)
                    rms = miller_set(cs, reindexed_miller_indices)
                    rms = rms.array(data)
                    # if params.d_min or params.d_max:
                    # rms = rms.resolution_filter(d_min=params.d_min, d_max=params.d_max)

                    # if map_to_asu:
                    # rms = rms.map_to_asu()

                    intensity, intensity_rdx = rms.common_sets(ms)
                    cc = intensity.correlation(intensity_rdx).coefficient()

                    ccs.append(cc)
                    offsets.append((h, k, l))
                    nref.append(intensity.size())

    return offsets, ccs, nref
Example #3
0
  def map_to_image_space(refl, d, dhs, dks, dls):
    from scitbx.array_family import flex
    d_elems = d.elems
    bb = refl.bounding_box
    dxs = d_elems[0] * dhs + d_elems[1] * dks + d_elems[2] * dls
    dys = d_elems[3] * dhs + d_elems[4] * dks + d_elems[5] * dls
    dzs = d_elems[6] * dhs + d_elems[7] * dks + d_elems[8] * dls
    xs = flex.floor(dxs + refl.image_coord_px[0]).iround() - bb[0]
    ys = flex.floor(dys + refl.image_coord_px[1]).iround() - bb[2]
    zs = flex.floor(dzs + refl.frame_number).iround() - bb[4]
    xyz = flex.vec3_int(zs, ys, xs)
    xyz = xyz.select((xs >= 0 and xs < (bb[1] - bb[0])) &
                     (ys >= 0 and ys < (bb[3] - bb[2])) &
                     (zs >= 0 and zs < (bb[5] - bb[4])))
    for _xyz in xyz:
      refl.shoebox[_xyz] += 1

    return
Example #4
0
  def map_to_image_space(refl, d, dhs, dks, dls):
    from scitbx.array_family import flex
    d_elems = d.elems
    bb = refl.bounding_box
    dxs = d_elems[0] * dhs + d_elems[1] * dks + d_elems[2] * dls
    dys = d_elems[3] * dhs + d_elems[4] * dks + d_elems[5] * dls
    dzs = d_elems[6] * dhs + d_elems[7] * dks + d_elems[8] * dls
    xs = flex.floor(dxs + refl.image_coord_px[0]).iround() - bb[0]
    ys = flex.floor(dys + refl.image_coord_px[1]).iround() - bb[2]
    zs = flex.floor(dzs + refl.frame_number).iround() - bb[4]
    xyz = flex.vec3_int(zs, ys, xs)
    xyz = xyz.select((xs >= 0 and xs < (bb[1] - bb[0])) &
                     (ys >= 0 and ys < (bb[3] - bb[2])) &
                     (zs >= 0 and zs < (bb[5] - bb[4])))
    for _xyz in xyz:
      refl.shoebox[_xyz] += 1

    return
Example #5
0
def get_indexing_offset_correlation_coefficients(reflections,
                                                 crystal,
                                                 grid,
                                                 d_min=None,
                                                 d_max=None,
                                                 map_to_asu=False,
                                                 grid_h=0,
                                                 grid_k=0,
                                                 grid_l=0,
                                                 reference=None):

    from dials.algorithms.symmetry import origin

    if grid:
        if grid_h == 0: grid_h = grid
        if grid_k == 0: grid_k = grid
        if grid_l == 0: grid_l = grid

    if True:
        return origin.get_hkl_offset_correlation_coefficients(
            reflections,
            crystal,
            map_to_asu=map_to_asu,
            grid_h=grid_h,
            grid_k=grid_k,
            grid_l=grid_l,
            reference=reference)

    from copy import deepcopy
    from dials.array_family import flex

    space_group = crystal.get_space_group()
    unit_cell = crystal.get_unit_cell()
    from cctbx.crystal import symmetry as crystal_symmetry
    cs = crystal_symmetry(unit_cell, space_group.type().lookup_symbol())

    from cctbx.miller import set as miller_set

    data = reflections['intensity.sum.value'] / \
           flex.sqrt(reflections['intensity.sum.variance'])

    if reference:
        reference = reference.select(reference['intensity.sum.variance'] > 0)
        reference_data = reference['intensity.sum.value'] / \
             flex.sqrt(reference['intensity.sum.variance'])
        reference_ms = miller_set(
            cs, reference['miller_index']).array(reference_data)
    else:
        reference_ms = None

    ccs = flex.double()
    offsets = flex.vec3_int()
    nref = flex.size_t()

    original_miller_indices = reflections['miller_index']
    ms = miller_set(cs, original_miller_indices).array(data)

    if d_min is not None or d_max is not None:
        ms = ms.resolution_filter(d_min=d_min, d_max=d_max)

    gh = gk = gl = grid
    if grid_h: gh = grid_h
    if grid_k: gk = grid_k
    if grid_l: gl = grid_l

    # essentially just inversion operation - this *should* have good CC - unless
    # we are working on a reference set where we don't reindex
    if reference:
        cb_op = sgtbx.change_of_basis_op('x,y,z')
    else:
        cb_op = sgtbx.change_of_basis_op('-x,-y,-z')

    for h in range(-gh, gh + 1):
        for k in range(-gk, gk + 1):
            for l in range(-gl, gl + 1):
                miller_indices = offset_miller_indices(ms.indices(), (h, k, l))
                reindexed_miller_indices = cb_op.apply(miller_indices)
                rms = miller_set(cs, reindexed_miller_indices).array(data)
                if reference_ms:
                    _ms = reference_ms
                else:
                    _ms = miller_set(cs, miller_indices).array(data)
                if map_to_asu:
                    rms = rms.map_to_asu()
                    _ms = _ms.map_to_asu()
                intensity, intensity_rdx = rms.common_sets(_ms)
                cc = intensity.correlation(intensity_rdx).coefficient()
                ccs.append(cc)
                offsets.append((h, k, l))
                nref.append(intensity.size())

    return offsets, ccs, nref
Example #6
0
def get_indexing_offset_correlation_coefficients(
    reflections, crystal, grid, d_min=None, d_max=None,
    map_to_asu=False, grid_h=0, grid_k=0, grid_l=0, reference=None):

  from dials.algorithms.symmetry import origin

  if grid:
    if grid_h == 0: grid_h = grid
    if grid_k == 0: grid_k = grid
    if grid_l == 0: grid_l = grid

  if True:
    return origin.get_hkl_offset_correlation_coefficients(
      reflections, crystal, map_to_asu=map_to_asu,
      grid_h=grid_h, grid_k=grid_k, grid_l=grid_l, reference=reference)

  from copy import deepcopy
  from dials.array_family import flex

  space_group = crystal.get_space_group()
  unit_cell = crystal.get_unit_cell()
  from cctbx.crystal import symmetry as crystal_symmetry
  cs = crystal_symmetry(unit_cell, space_group.type().lookup_symbol())

  from cctbx.miller import set as miller_set

  data = reflections['intensity.sum.value'] / \
         flex.sqrt(reflections['intensity.sum.variance'])

  if reference:
    reference = reference.select(reference['intensity.sum.variance'] > 0)
    reference_data = reference['intensity.sum.value'] / \
         flex.sqrt(reference['intensity.sum.variance'])
    reference_ms = miller_set(cs, reference['miller_index']).array(
      reference_data)
  else:
    reference_ms = None

  ccs = flex.double()
  offsets = flex.vec3_int()
  nref = flex.size_t()

  original_miller_indices = reflections['miller_index']
  ms = miller_set(cs, original_miller_indices).array(data)

  if d_min is not None or d_max is not None:
    ms = ms.resolution_filter(d_min=d_min, d_max=d_max)

  gh = gk = gl = grid
  if grid_h: gh = grid_h
  if grid_k: gk = grid_k
  if grid_l: gl = grid_l

  # essentially just inversion operation - this *should* have good CC - unless
  # we are working on a reference set where we don't reindex
  if reference:
    cb_op = sgtbx.change_of_basis_op('x,y,z')
  else:
    cb_op = sgtbx.change_of_basis_op('-x,-y,-z')

  for h in range(-gh, gh + 1):
    for k in range(-gk, gk + 1):
      for l in range(-gl, gl + 1):
        miller_indices = offset_miller_indices(ms.indices(), (h, k, l))
        reindexed_miller_indices = cb_op.apply(miller_indices)
        rms = miller_set(cs, reindexed_miller_indices).array(data)
        if reference_ms:
          _ms = reference_ms
        else:
          _ms = miller_set(cs, miller_indices).array(data)
        if map_to_asu:
          rms = rms.map_to_asu()
          _ms = _ms.map_to_asu()
        intensity, intensity_rdx = rms.common_sets(_ms)
        cc = intensity.correlation(intensity_rdx).coefficient()
        ccs.append(cc)
        offsets.append((h, k, l))
        nref.append(intensity.size())

  return offsets, ccs, nref