def tst_with_old_index_generator(self):
     from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
     from dials.array_family import flex
     predict = ScanStaticReflectionPredictor(self.experiments[0])
     r_old = predict.for_ub_old_index_generator(
         self.experiments[0].crystal.get_A())
     r_new = predict.for_ub(self.experiments[0].crystal.get_A())
     index1 = flex.size_t(
         sorted(range(len(r_old)), key=lambda x: r_old['miller_index'][x]))
     index2 = flex.size_t(
         sorted(range(len(r_new)), key=lambda x: r_new['miller_index'][x]))
     r_old = r_old.select(index1)
     r_new = r_new.select(index2)
     assert (len(r_old) == len(r_new))
     eps = 1e-7
     for r1, r2 in zip(r_old.rows(), r_new.rows()):
         assert (r1['miller_index'] == r2['miller_index'])
         assert (r1['panel'] == r2['panel'])
         assert (r1['entering'] == r2['entering'])
         assert (all(abs(a - b) < eps for a, b in zip(r1['s1'], r2['s1'])))
         assert (all(
             abs(a - b) < eps
             for a, b in zip(r1['xyzcal.px'], r2['xyzcal.px'])))
         assert (all(
             abs(a - b) < eps
             for a, b in zip(r1['xyzcal.mm'], r2['xyzcal.mm'])))
     print 'OK'
Example #2
0
def test_with_old_index_generator(data):
    from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
    from dials.array_family import flex

    predict = ScanStaticReflectionPredictor(data.experiments[0])
    r_old = predict.for_ub_old_index_generator(
        data.experiments[0].crystal.get_A())
    r_new = predict.for_ub(data.experiments[0].crystal.get_A())
    index1 = flex.size_t(
        sorted(range(len(r_old)), key=lambda x: r_old["miller_index"][x]))
    index2 = flex.size_t(
        sorted(range(len(r_new)), key=lambda x: r_new["miller_index"][x]))
    r_old = r_old.select(index1)
    r_new = r_new.select(index2)
    assert len(r_old) == len(r_new)
    for r1, r2 in zip(r_old.rows(), r_new.rows()):
        assert r1["miller_index"] == r2["miller_index"]
        assert r1["panel"] == r2["panel"]
        assert r1["entering"] == r2["entering"]
        assert all(a == pytest.approx(b, abs=1e-7)
                   for a, b in zip(r1["s1"], r2["s1"]))
        assert all(a == pytest.approx(b, abs=1e-7)
                   for a, b in zip(r1["xyzcal.px"], r2["xyzcal.px"]))
        assert all(a == pytest.approx(b, abs=1e-7)
                   for a, b in zip(r1["xyzcal.mm"], r2["xyzcal.mm"]))
 def predict_new(self, experiment=None, hkl=None, panel=None):
   from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
   if experiment is None: experiment=self.experiments[0]
   predict = ScanStaticReflectionPredictor(experiment)
   if hkl is None:
     return predict.for_ub(experiment.crystal.get_A())
   else:
     if panel is None:
       return predict(hkl)
     else:
       return predict(hkl, panel)
Example #4
0
 def predict_new(self, experiment=None, hkl=None, panel=None):
     from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
     if experiment is None: experiment = self.experiments[0]
     predict = ScanStaticReflectionPredictor(experiment)
     if hkl is None:
         return predict.for_ub(experiment.crystal.get_A())
     else:
         if panel is None:
             return predict(hkl)
         else:
             return predict(hkl, panel)
def test_with_reflection_table(data):
  from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
  from dials.array_family import flex
  r_old = data.reflections
  r_new = flex.reflection_table()
  r_new['miller_index'] = r_old['miller_index']
  r_new['panel'] = r_old['panel']
  r_new['entering'] = r_old['entering']
  predict = ScanStaticReflectionPredictor(data.experiments[0])
  predict.for_reflection_table(r_new, data.experiments[0].crystal.get_A())
  for r1, r2 in zip(r_old.rows(), r_new.rows()):
    assert r1['miller_index'] == r2['miller_index']
    assert r1['panel'] == r2['panel']
    assert r1['entering'] == r2['entering']
    assert all(a == pytest.approx(b, abs=1e-7) for a, b in zip(r1['s1'], r2['s1']))
    assert all(a == pytest.approx(b, abs=1e-7) for a, b in zip(r1['xyzcal.px'], r2['xyzcal.px']))
    assert all(a == pytest.approx(b, abs=1e-7) for a, b in zip(r1['xyzcal.mm'], r2['xyzcal.mm']))
 def tst_with_reflection_table(self):
   from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
   from dials.array_family import flex
   r_old = self.reflections
   r_new = flex.reflection_table()
   r_new['miller_index'] = r_old['miller_index']
   r_new['panel'] = r_old['panel']
   r_new['entering'] = r_old['entering']
   predict = ScanStaticReflectionPredictor(self.experiments[0])
   predict.for_reflection_table(r_new, self.experiments[0].crystal.get_A())
   eps = 1e-7
   for r1, r2 in zip(r_old.rows(), r_new.rows()):
     assert(r1['miller_index'] == r2['miller_index'])
     assert(r1['panel'] == r2['panel'])
     assert(r1['entering'] == r2['entering'])
     assert(all(abs(a-b) < eps for a, b in zip(r1['s1'], r2['s1'])))
     assert(all(abs(a-b) < eps for a, b in zip(r1['xyzcal.px'], r2['xyzcal.px'])))
     assert(all(abs(a-b) < eps for a, b in zip(r1['xyzcal.mm'], r2['xyzcal.mm'])))
   print 'OK'
Example #7
0
def test_connected_components_centred_cell(dials_data):
    experiment = ExperimentList.from_file(
        dials_data("insulin_processed").join("scaled.expt").strpath, check_format=False
    )[0]

    experiment.scan.set_image_range((1, 10))
    predict = ScanStaticReflectionPredictor(experiment, dmin=3, margin=1)
    refl = predict.for_ub(experiment.crystal.get_A())
    miller_set = miller.set(
        experiment.crystal.get_crystal_symmetry(),
        refl["miller_index"],
        anomalous_flag=False,
    )
    miller_array = miller_set.d_spacings().resolution_filter(d_min=3)
    complete_set, unique_ms = missing_reflections.connected_components(miller_array)
    assert [ms.size() for ms in unique_ms] == [581, 32, 29, 6, 3, 3, 3, 2]
    # Verify that all the indices reported missing are actually missing from the input
    for ms in unique_ms:
        assert ms.common_set(miller_array.map_to_asu()).size() == 0
    assert complete_set.completeness() == 1
Example #8
0
def test_for_reflection_table(data):
    from dials.algorithms.spot_prediction import (
        ScanStaticReflectionPredictor,
        ScanVaryingReflectionPredictor,
    )
    from dials.array_family import flex

    predict = ScanStaticReflectionPredictor(data.experiments[0])
    preds = predict.for_ub(data.experiments[0].crystal.get_A())

    preds["ub_matrix"] = flex.mat3_double(len(preds),
                                          data.experiments[0].crystal.get_A())
    preds["s0"] = flex.vec3_double(len(preds),
                                   data.experiments[0].beam.get_s0())
    preds["d_matrix"] = flex.mat3_double(len(preds))
    preds["S_matrix"] = flex.mat3_double(
        len(preds), data.experiments[0].goniometer.get_setting_rotation())
    for ipanel, panel in enumerate(data.experiments[0].detector):
        sel = preds["panel"] == ipanel
        D = panel.get_d_matrix()
        preds["d_matrix"].set_selected(sel, D)
    predict = ScanVaryingReflectionPredictor(data.experiments[0])
    old_preds = copy.deepcopy(preds)
    predict.for_reflection_table(preds, preds["ub_matrix"], preds["s0"],
                                 preds["d_matrix"], preds["S_matrix"])

    # Because UB, s0, d and S values are the same for all reflections, the new
    # reflections should be approx equal to those produced by the scan static
    # predictor
    old_x, old_y, old_z = old_preds["xyzcal.px"].parts()
    new_x, new_y, new_z = preds["xyzcal.px"].parts()
    assert old_x.all_approx_equal(new_x)
    assert old_y.all_approx_equal(new_y)
    assert old_z.all_approx_equal(new_z)
  def tst_for_reflection_table(self):
    from libtbx.test_utils import approx_equal
    from dials.algorithms.spot_prediction import \
      ScanVaryingReflectionPredictor, ScanStaticReflectionPredictor
    from dials.array_family import flex

    predict = ScanStaticReflectionPredictor(self.experiments[0])
    preds = predict.for_ub(self.experiments[0].crystal.get_A())

    preds['ub_matrix'] = flex.mat3_double(len(preds), self.experiments[0].crystal.get_A())
    preds['s0'] = flex.vec3_double(len(preds), self.experiments[0].beam.get_s0())
    preds['d_matrix'] = flex.mat3_double(len(preds))
    for ipanel, panel in enumerate(self.experiments[0].detector):
      sel = preds['panel'] == ipanel
      D = panel.get_d_matrix()
      preds['d_matrix'].set_selected(sel, D)
    predict = ScanVaryingReflectionPredictor(self.experiments[0])
    from copy import deepcopy
    old_preds = deepcopy(preds)
    predict.for_reflection_table(preds,
                                 preds['ub_matrix'],
                                 preds['s0'],
                                 preds['d_matrix'])

    # Because UB, s0 and d values are the same for all reflections, the new
    # reflections should be approx equal to those produced by the scan static
    # predictor
    old_x, old_y, old_z = old_preds['xyzcal.px'].parts()
    new_x, new_y, new_z = preds['xyzcal.px'].parts()
    assert old_x.all_approx_equal(new_x)
    assert old_y.all_approx_equal(new_y)
    assert old_z.all_approx_equal(new_z)

    print "OK"

    return
Example #10
0
 def tst_with_reflection_table(self):
     from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
     from dials.array_family import flex
     r_old = self.reflections
     r_new = flex.reflection_table()
     r_new['miller_index'] = r_old['miller_index']
     r_new['panel'] = r_old['panel']
     r_new['entering'] = r_old['entering']
     predict = ScanStaticReflectionPredictor(self.experiments[0])
     predict.for_reflection_table(r_new,
                                  self.experiments[0].crystal.get_A())
     eps = 1e-7
     for r1, r2 in zip(r_old.rows(), r_new.rows()):
         assert (r1['miller_index'] == r2['miller_index'])
         assert (r1['panel'] == r2['panel'])
         assert (r1['entering'] == r2['entering'])
         assert (all(abs(a - b) < eps for a, b in zip(r1['s1'], r2['s1'])))
         assert (all(
             abs(a - b) < eps
             for a, b in zip(r1['xyzcal.px'], r2['xyzcal.px'])))
         assert (all(
             abs(a - b) < eps
             for a, b in zip(r1['xyzcal.mm'], r2['xyzcal.mm'])))
     print 'OK'
Example #11
0
def test_connected_components(dials_data):
    experiment = ExperimentList.from_file(
        dials_data("centroid_test_data").join("experiments.json").strpath
    )[0]

    image_ranges = [(1, 9), (1, 100), (1, 1000)]
    expected_ms_sizes = [[755], [242, 14, 10, 5, 2, 2, 2], []]
    for image_range, expected_sizes in zip(image_ranges, expected_ms_sizes):
        experiment.scan.set_image_range(image_range)
        predict = ScanStaticReflectionPredictor(experiment, dmin=3, margin=1)
        refl = predict.for_ub(experiment.crystal.get_A())
        miller_set = miller.set(
            experiment.crystal.get_crystal_symmetry(),
            refl["miller_index"],
            anomalous_flag=False,
        )
        miller_array = miller_set.d_spacings().resolution_filter(d_min=3)
        complete_set, unique_ms = missing_reflections.connected_components(miller_array)
        assert len(unique_ms) == len(expected_sizes)
        assert [ms.size() for ms in unique_ms] == expected_sizes
        # Verify that all the indices reported missing are actually missing from the input
        for ms in unique_ms:
            assert ms.common_set(miller_array.map_to_asu()).size() == 0
        assert complete_set.completeness() == 1
Example #12
0
  def tst_for_reflection_table(self):
    from libtbx.test_utils import approx_equal
    from dials.algorithms.spot_prediction import \
      ScanVaryingReflectionPredictor, ScanStaticReflectionPredictor
    from dials.array_family import flex

    predict = ScanStaticReflectionPredictor(self.experiments[0])
    preds = predict.for_ub(self.experiments[0].crystal.get_A())

    preds['ub_matrix'] = flex.mat3_double(len(preds), self.experiments[0].crystal.get_A())
    preds['s0'] = flex.vec3_double(len(preds), self.experiments[0].beam.get_s0())
    preds['d_matrix'] = flex.mat3_double(len(preds))
    preds['S_matrix'] = flex.mat3_double(len(preds),
        self.experiments[0].goniometer.get_setting_rotation())
    for ipanel, panel in enumerate(self.experiments[0].detector):
      sel = preds['panel'] == ipanel
      D = panel.get_d_matrix()
      preds['d_matrix'].set_selected(sel, D)
    predict = ScanVaryingReflectionPredictor(self.experiments[0])
    from copy import deepcopy
    old_preds = deepcopy(preds)
    predict.for_reflection_table(preds,
                                 preds['ub_matrix'],
                                 preds['s0'],
                                 preds['d_matrix'],
                                 preds['S_matrix'])

    # Because UB, s0, d and S values are the same for all reflections, the new
    # reflections should be approx equal to those produced by the scan static
    # predictor
    old_x, old_y, old_z = old_preds['xyzcal.px'].parts()
    new_x, new_y, new_z = preds['xyzcal.px'].parts()
    assert old_x.all_approx_equal(new_x)
    assert old_y.all_approx_equal(new_y)
    assert old_z.all_approx_equal(new_z)

    print "OK"

    return
    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
Example #14
0
def export_sadabs(integrated_data, experiment_list, params):
    """Export data from integrated_data corresponding to experiment_list to a
    file for input to SADABS. FIXME probably need to make a .p4p file as
    well..."""

    from dials.array_family import flex

    # for the moment assume (and assert) that we will convert data from exactly
    # one lattice...

    assert len(experiment_list) == 1
    # select reflections that are assigned to an experiment (i.e. non-negative id)

    integrated_data = integrated_data.select(integrated_data["id"] >= 0)
    assert max(integrated_data["id"]) == 0

    # export for sadabs should only be for non-scaled reflections
    assert any(i in integrated_data
               for i in ["intensity.sum.value", "intensity.prf.value"])

    integrated_data = filter_reflection_table(
        integrated_data,
        intensity_choice=params.intensity,
        partiality_threshold=params.mtz.partiality_threshold,
        combine_partials=params.mtz.combine_partials,
        min_isigi=params.mtz.min_isigi,
        filter_ice_rings=params.mtz.filter_ice_rings,
        d_min=params.mtz.d_min,
    )

    experiment = experiment_list[0]
    assert experiment.scan is not None

    # sort data before output
    nref = len(integrated_data["miller_index"])
    indices = flex.size_t_range(nref)
    perm = sorted(indices, key=lambda k: integrated_data["miller_index"][k])
    integrated_data = integrated_data.select(flex.size_t(perm))

    assert experiment.goniometer is not None

    # Warn of unhelpful SADABS behaviour for certain multi-sequence data sets
    hkl_file_root, _ = os.path.splitext(params.sadabs.hklout)
    if not params.sadabs.run or re.search("_0+$", hkl_file_root):
        logger.warning(
            "It seems SADABS rejects multi-sequence data when the first "
            "filename ends "
            "'_0', '_00', etc., with a cryptic error message:\n"
            "\t'Inconsistent 2theta values in same scan'.\n"
            "You may need to begin the numbering of your SADABS HKL files from 1, "
            "rather than 0, and ensure the SADABS run/batch number is greater than 0."
        )

    axis = matrix.col(experiment.goniometer.get_rotation_axis_datum())

    beam = matrix.col(experiment.beam.get_sample_to_source_direction())
    s0 = matrix.col(experiment.beam.get_s0())

    F = matrix.sqr(experiment.goniometer.get_fixed_rotation())
    S = matrix.sqr(experiment.goniometer.get_setting_rotation())
    unit_cell = experiment.crystal.get_unit_cell()

    if params.debug:
        m_format = "%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f"
        c_format = "%.2f %.2f %.2f %.2f %.2f %.2f"

        logger.info(
            "Unit cell parameters from experiment: %s",
            c_format % unit_cell.parameters(),
        )
        logger.info(
            "Symmetry: %s",
            experiment.crystal.get_space_group().type().lookup_symbol())

        logger.info("Goniometer fixed matrix:\n%s", m_format % F.elems)
        logger.info("Goniometer setting matrix:\n%s", m_format % S.elems)
        logger.info("Goniometer scan axis:\n%6.3f%6.3f%6.3f", axis.elems)

    # detector scaling info
    assert len(experiment.detector) == 1
    panel = experiment.detector[0]
    dims = panel.get_image_size()
    pixel = panel.get_pixel_size()
    fast_axis = matrix.col(panel.get_fast_axis())
    slow_axis = matrix.col(panel.get_slow_axis())
    normal = fast_axis.cross(slow_axis)
    detector2t = s0.angle(normal, deg=True)

    if params.debug:
        logger.info("Detector fast, slow axes:")
        logger.info("%6.3f%6.3f%6.3f", fast_axis.elems)
        logger.info("%6.3f%6.3f%6.3f", slow_axis.elems)
        logger.info("Detector two theta (degrees): %.2f", detector2t)

    scl_x = 512.0 / (dims[0] * pixel[0])
    scl_y = 512.0 / (dims[1] * pixel[1])

    image_range = experiment.scan.get_image_range()

    from cctbx.array_family import flex as cflex  # implicit import # noqa: F401
    from cctbx.miller import map_to_asu_isym  # implicit import # noqa: F401

    # gather the required information for the reflection file

    nref = len(integrated_data["miller_index"])

    miller_index = integrated_data["miller_index"]

    if "intensity.sum.value" in integrated_data:
        I = integrated_data["intensity.sum.value"]
        V = integrated_data["intensity.sum.variance"]
        assert V.all_gt(0)
        sigI = flex.sqrt(V)
    else:
        I = integrated_data["intensity.prf.value"]
        V = integrated_data["intensity.prf.variance"]
        assert V.all_gt(0)
        sigI = flex.sqrt(V)

    # figure out scaling to make sure data fit into format 2F8.2 i.e. Imax < 1e5

    Imax = flex.max(I)

    if params.debug:
        logger.info("Maximum intensity in file: %8.2f", Imax)

    if Imax > 99999.0:
        scale = 99999.0 / Imax
        I = I * scale
        sigI = sigI * scale

    phi_start, phi_range = experiment.scan.get_image_oscillation(
        image_range[0])

    if params.sadabs.predict:
        logger.info("Using scan static predicted spot locations")
        from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor

        predictor = ScanStaticReflectionPredictor(experiment)
        UB = experiment.crystal.get_A()
        predictor.for_reflection_table(integrated_data, UB)

    if not experiment.crystal.num_scan_points:
        logger.info("No scan varying model: use static")
        static = True
    else:
        static = False

    with open(params.sadabs.hklout, "w") as fout:

        for j in range(nref):

            h, k, l = miller_index[j]

            if params.sadabs.predict:
                x_mm, y_mm, z_rad = integrated_data["xyzcal.mm"][j]
            else:
                x_mm, y_mm, z_rad = integrated_data["xyzobs.mm.value"][j]

            z0 = integrated_data["xyzcal.px"][j][2]
            istol = int(round(10000 * unit_cell.stol((h, k, l))))

            if params.sadabs.predict or static:
                # work from a scan static model & assume perfect goniometer
                # FIXME maybe should work back in the option to predict spot positions
                UB = matrix.sqr(experiment.crystal.get_A())
                phi = phi_start + z0 * phi_range
                R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
                RUB = S * R * F * UB
            else:
                # properly compute RUB for every reflection
                UB = matrix.sqr(
                    experiment.crystal.get_A_at_scan_point(int(round(z0))))
                phi = phi_start + z0 * phi_range
                R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
                RUB = S * R * F * UB

            x = RUB * (h, k, l)
            s = (s0 + x).normalize()

            # can also compute s based on centre of mass of spot
            # s = (origin + x_mm * fast_axis + y_mm * slow_axis).normalize()

            astar = (RUB * (1, 0, 0)).normalize()
            bstar = (RUB * (0, 1, 0)).normalize()
            cstar = (RUB * (0, 0, 1)).normalize()

            ix = beam.dot(astar)
            iy = beam.dot(bstar)
            iz = beam.dot(cstar)

            dx = s.dot(astar)
            dy = s.dot(bstar)
            dz = s.dot(cstar)

            x = x_mm * scl_x
            y = y_mm * scl_y
            z = (z_rad * 180 / math.pi - phi_start) / phi_range

            fout.write("%4d%4d%4d%8.2f%8.2f%4d%8.5f%8.5f%8.5f%8.5f%8.5f%8.5f" %
                       (h, k, l, I[j], sigI[j], params.sadabs.run, ix, dx, iy,
                        dy, iz, dz))
            fout.write("%7.2f%7.2f%8.2f%7.2f%5d\n" %
                       (x, y, z, detector2t, istol))

    fout.close()
    logger.info("Output %d reflections to %s", nref, params.sadabs.hklout)
Example #15
0
def export_sadabs(integrated_data, experiment_list, hklout, run=0,
                  summation=False, include_partials=False, keep_partials=False,
                  debug=False, predict=True):
  '''Export data from integrated_data corresponding to experiment_list to a
  file for input to SADABS. FIXME probably need to make a .p4p file as
  well...'''

  from dials.array_family import flex
  from scitbx import matrix
  import math

  # for the moment assume (and assert) that we will convert data from exactly
  # one lattice...

  assert(len(experiment_list) == 1)
  # select reflections that are assigned to an experiment (i.e. non-negative id)

  integrated_data = integrated_data.select(integrated_data['id'] >= 0)
  assert max(integrated_data['id']) == 0

  if not summation:
    assert('intensity.prf.value' in integrated_data)

  # strip out negative variance reflections: these should not really be there
  # FIXME Doing select on summation results. Should do on profile result if
  # present? Yes

  if 'intensity.prf.variance' in integrated_data:
    selection = integrated_data.get_flags(
      integrated_data.flags.integrated,
      all=True)
  else:
    selection = integrated_data.get_flags(
      integrated_data.flags.integrated_sum)
  integrated_data = integrated_data.select(selection)

  selection = integrated_data['intensity.sum.variance'] <= 0
  if selection.count(True) > 0:
    integrated_data.del_selected(selection)
    logger.info('Removing %d reflections with negative variance' % \
          selection.count(True))

  if 'intensity.prf.variance' in integrated_data:
    selection = integrated_data['intensity.prf.variance'] <= 0
    if selection.count(True) > 0:
      integrated_data.del_selected(selection)
      logger.info('Removing %d profile reflections with negative variance' % \
            selection.count(True))

  if include_partials:
    integrated_data = sum_partial_reflections(integrated_data)
    integrated_data = scale_partial_reflections(integrated_data)

  if 'partiality' in integrated_data:
    selection = integrated_data['partiality'] < 0.99
    if selection.count(True) > 0 and not keep_partials:
      integrated_data.del_selected(selection)
      logger.info('Removing %d incomplete reflections' % \
        selection.count(True))

  experiment = experiment_list[0]
  assert(not experiment.scan is None)

  # sort data before output
  nref = len(integrated_data['miller_index'])
  indices = flex.size_t_range(nref)
  perm = sorted(indices, key=lambda k: integrated_data['miller_index'][k])
  integrated_data = integrated_data.select(flex.size_t(perm))

  assert (not experiment.goniometer is None)

  axis = matrix.col(experiment.goniometer.get_rotation_axis_datum())

  beam = matrix.col(experiment.beam.get_direction())
  s0 = matrix.col(experiment.beam.get_s0())

  F = matrix.sqr(experiment.goniometer.get_fixed_rotation())
  S = matrix.sqr(experiment.goniometer.get_setting_rotation())
  unit_cell = experiment.crystal.get_unit_cell()

  if debug:
    m_format = '%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f'
    c_format = '%.2f %.2f %.2f %.2f %.2f %.2f'

    logger.info('Unit cell parameters from experiment: %s' % (c_format %
         unit_cell.parameters()))
    logger.info('Symmetry: %s' % experiment.crystal.get_space_group().type(
         ).lookup_symbol())

    logger.info('Goniometer fixed matrix:\n%s' % (m_format % F.elems))
    logger.info('Goniometer setting matrix:\n%s' % (m_format % S.elems))
    logger.info('Goniometer scan axis:\n%6.3f%6.3f%6.3f' % (axis.elems))

  # detector scaling info
  assert(len(experiment.detector) == 1)
  panel = experiment.detector[0]
  dims = panel.get_image_size()
  pixel = panel.get_pixel_size()
  fast_axis = matrix.col(panel.get_fast_axis())
  slow_axis = matrix.col(panel.get_slow_axis())
  normal = fast_axis.cross(slow_axis)
  detector2t = s0.angle(normal, deg=True)
  origin = matrix.col(panel.get_origin())

  if debug:
    logger.info('Detector fast, slow axes:')
    logger.info('%6.3f%6.3f%6.3f' % (fast_axis.elems))
    logger.info('%6.3f%6.3f%6.3f' % (slow_axis.elems))
    logger.info('Detector two theta (degrees): %.2f' % detector2t)

  scl_x = 512.0 / (dims[0] * pixel[0])
  scl_y = 512.0 / (dims[1] * pixel[1])

  image_range = experiment.scan.get_image_range()

  from cctbx.array_family import flex as cflex # implicit import
  from cctbx.miller import map_to_asu_isym # implicit import

  # gather the required information for the reflection file

  nref = len(integrated_data['miller_index'])
  zdet = flex.double(integrated_data['xyzcal.px'].parts()[2])

  miller_index = integrated_data['miller_index']

  I = None
  sigI = None

  # export including scale factors

  if 'lp' in integrated_data:
    lp = integrated_data['lp']
  else:
    lp = flex.double(nref, 1.0)
  if 'dqe' in integrated_data:
    dqe = integrated_data['dqe']
  else:
    dqe = flex.double(nref, 1.0)
  scl = lp / dqe

  if summation:
    I = integrated_data['intensity.sum.value'] * scl
    V = integrated_data['intensity.sum.variance'] * scl * scl
    assert V.all_gt(0)
    sigI = flex.sqrt(V)
  else:
    I = integrated_data['intensity.prf.value'] * scl
    V = integrated_data['intensity.prf.variance'] * scl * scl
    assert V.all_gt(0)
    sigI = flex.sqrt(V)

  # figure out scaling to make sure data fit into format 2F8.2 i.e. Imax < 1e5

  Imax = flex.max(I)

  if debug:
    logger.info('Maximum intensity in file: %8.2f' % Imax)

  if Imax > 99999.0:
    scale = 99999.0 / Imax
    I = I * scale
    sigI = sigI * scale

  phi_start, phi_range = experiment.scan.get_image_oscillation(image_range[0])

  if predict:
    logger.info('Using scan static predicted spot locations')
    from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
    predictor = ScanStaticReflectionPredictor(experiment)
    UB = experiment.crystal.get_A()
    predictor.for_reflection_table(integrated_data, UB)

  if not experiment.crystal.num_scan_points:
    logger.info('No scan varying model: use static')
    static = True
  else:
    static = False

  fout = open(hklout, 'w')

  for j in range(nref):

    h, k, l = miller_index[j]

    if predict:
      x_mm, y_mm, z_rad = integrated_data['xyzcal.mm'][j]
    else:
      x_mm, y_mm, z_rad = integrated_data['xyzobs.mm.value'][j]

    z0 = integrated_data['xyzcal.px'][j][2]
    istol = int(round(10000 * unit_cell.stol((h, k, l))))

    if predict or static:
      # work from a scan static model & assume perfect goniometer
      # FIXME maybe should work back in the option to predict spot positions
      UB = experiment.crystal.get_A()
      phi = phi_start + z0 * phi_range
      R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
      RUB = S * R * F * UB
    else:
      # properly compute RUB for every reflection
      UB = experiment.crystal.get_A_at_scan_point(int(round(z0)))
      phi = phi_start + z0 * phi_range
      R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
      RUB = S * R * F * UB

    x = RUB * (h, k, l)
    s = (s0 + x).normalize()

    # can also compute s based on centre of mass of spot
    # s = (origin + x_mm * fast_axis + y_mm * slow_axis).normalize()

    astar = (RUB * (1, 0, 0)).normalize()
    bstar = (RUB * (0, 1, 0)).normalize()
    cstar = (RUB * (0, 0, 1)).normalize()

    ix = beam.dot(astar)
    iy = beam.dot(bstar)
    iz = beam.dot(cstar)

    dx = s.dot(astar)
    dy = s.dot(bstar)
    dz = s.dot(cstar)

    x = x_mm * scl_x
    y = y_mm * scl_y
    z = (z_rad * 180 / math.pi - phi_start) / phi_range

    fout.write('%4d%4d%4d%8.2f%8.2f%4d%8.5f%8.5f%8.5f%8.5f%8.5f%8.5f' % \
               (h, k, l, I[j], sigI[j], run, ix, dx, iy, dy, iz, dz))
    fout.write('%7.2f%7.2f%8.2f%7.2f%5d\n' % (x, y, z, detector2t, istol))

  fout.close()
  logger.info('Output %d reflections to %s' % (nref, hklout))
  return
Example #16
0
    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
Example #17
0
def export_sadabs(integrated_data,
                  experiment_list,
                  hklout,
                  run=0,
                  summation=False,
                  include_partials=False,
                  keep_partials=False,
                  debug=False,
                  predict=True):
    '''Export data from integrated_data corresponding to experiment_list to a
  file for input to SADABS. FIXME probably need to make a .p4p file as
  well...'''

    from dials.array_family import flex
    from scitbx import matrix
    import math

    # for the moment assume (and assert) that we will convert data from exactly
    # one lattice...

    assert (len(experiment_list) == 1)
    # select reflections that are assigned to an experiment (i.e. non-negative id)

    integrated_data = integrated_data.select(integrated_data['id'] >= 0)
    assert max(integrated_data['id']) == 0

    if not summation:
        assert ('intensity.prf.value' in integrated_data)

    # strip out negative variance reflections: these should not really be there
    # FIXME Doing select on summation results. Should do on profile result if
    # present? Yes

    if 'intensity.prf.variance' in integrated_data:
        selection = integrated_data.get_flags(integrated_data.flags.integrated,
                                              all=True)
    else:
        selection = integrated_data.get_flags(
            integrated_data.flags.integrated_sum)
    integrated_data = integrated_data.select(selection)

    selection = integrated_data['intensity.sum.variance'] <= 0
    if selection.count(True) > 0:
        integrated_data.del_selected(selection)
        logger.info('Removing %d reflections with negative variance' % \
              selection.count(True))

    if 'intensity.prf.variance' in integrated_data:
        selection = integrated_data['intensity.prf.variance'] <= 0
        if selection.count(True) > 0:
            integrated_data.del_selected(selection)
            logger.info('Removing %d profile reflections with negative variance' % \
                  selection.count(True))

    if include_partials:
        integrated_data = sum_partial_reflections(integrated_data)
        integrated_data = scale_partial_reflections(integrated_data)

    if 'partiality' in integrated_data:
        selection = integrated_data['partiality'] < 0.99
        if selection.count(True) > 0 and not keep_partials:
            integrated_data.del_selected(selection)
            logger.info('Removing %d incomplete reflections' % \
              selection.count(True))

    experiment = experiment_list[0]
    assert (not experiment.scan is None)

    # sort data before output
    nref = len(integrated_data['miller_index'])
    indices = flex.size_t_range(nref)
    perm = sorted(indices, key=lambda k: integrated_data['miller_index'][k])
    integrated_data = integrated_data.select(flex.size_t(perm))

    assert (not experiment.goniometer is None)

    axis = matrix.col(experiment.goniometer.get_rotation_axis_datum())

    beam = matrix.col(experiment.beam.get_direction())
    s0 = matrix.col(experiment.beam.get_s0())

    F = matrix.sqr(experiment.goniometer.get_fixed_rotation())
    S = matrix.sqr(experiment.goniometer.get_setting_rotation())
    unit_cell = experiment.crystal.get_unit_cell()

    if debug:
        m_format = '%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f\n%6.3f%6.3f%6.3f'
        c_format = '%.2f %.2f %.2f %.2f %.2f %.2f'

        logger.info('Unit cell parameters from experiment: %s' %
                    (c_format % unit_cell.parameters()))
        logger.info(
            'Symmetry: %s' %
            experiment.crystal.get_space_group().type().lookup_symbol())

        logger.info('Goniometer fixed matrix:\n%s' % (m_format % F.elems))
        logger.info('Goniometer setting matrix:\n%s' % (m_format % S.elems))
        logger.info('Goniometer scan axis:\n%6.3f%6.3f%6.3f' % (axis.elems))

    # detector scaling info
    assert (len(experiment.detector) == 1)
    panel = experiment.detector[0]
    dims = panel.get_image_size()
    pixel = panel.get_pixel_size()
    fast_axis = matrix.col(panel.get_fast_axis())
    slow_axis = matrix.col(panel.get_slow_axis())
    normal = fast_axis.cross(slow_axis)
    detector2t = s0.angle(normal, deg=True)
    origin = matrix.col(panel.get_origin())

    if debug:
        logger.info('Detector fast, slow axes:')
        logger.info('%6.3f%6.3f%6.3f' % (fast_axis.elems))
        logger.info('%6.3f%6.3f%6.3f' % (slow_axis.elems))
        logger.info('Detector two theta (degrees): %.2f' % detector2t)

    scl_x = 512.0 / (dims[0] * pixel[0])
    scl_y = 512.0 / (dims[1] * pixel[1])

    image_range = experiment.scan.get_image_range()

    from cctbx.array_family import flex as cflex  # implicit import
    from cctbx.miller import map_to_asu_isym  # implicit import

    # gather the required information for the reflection file

    nref = len(integrated_data['miller_index'])
    zdet = flex.double(integrated_data['xyzcal.px'].parts()[2])

    miller_index = integrated_data['miller_index']

    I = None
    sigI = None

    # export including scale factors

    if 'lp' in integrated_data:
        lp = integrated_data['lp']
    else:
        lp = flex.double(nref, 1.0)
    if 'qe' in integrated_data:
        qe = integrated_data['qe']
    elif 'dqe' in integrated_data:
        qe = integrated_data['dqe']
    else:
        qe = flex.double(nref, 1.0)
    scl = lp / qe

    if summation:
        I = integrated_data['intensity.sum.value'] * scl
        V = integrated_data['intensity.sum.variance'] * scl * scl
        assert V.all_gt(0)
        sigI = flex.sqrt(V)
    else:
        I = integrated_data['intensity.prf.value'] * scl
        V = integrated_data['intensity.prf.variance'] * scl * scl
        assert V.all_gt(0)
        sigI = flex.sqrt(V)

    # figure out scaling to make sure data fit into format 2F8.2 i.e. Imax < 1e5

    Imax = flex.max(I)

    if debug:
        logger.info('Maximum intensity in file: %8.2f' % Imax)

    if Imax > 99999.0:
        scale = 99999.0 / Imax
        I = I * scale
        sigI = sigI * scale

    phi_start, phi_range = experiment.scan.get_image_oscillation(
        image_range[0])

    if predict:
        logger.info('Using scan static predicted spot locations')
        from dials.algorithms.spot_prediction import ScanStaticReflectionPredictor
        predictor = ScanStaticReflectionPredictor(experiment)
        UB = experiment.crystal.get_A()
        predictor.for_reflection_table(integrated_data, UB)

    if not experiment.crystal.num_scan_points:
        logger.info('No scan varying model: use static')
        static = True
    else:
        static = False

    fout = open(hklout, 'w')

    for j in range(nref):

        h, k, l = miller_index[j]

        if predict:
            x_mm, y_mm, z_rad = integrated_data['xyzcal.mm'][j]
        else:
            x_mm, y_mm, z_rad = integrated_data['xyzobs.mm.value'][j]

        z0 = integrated_data['xyzcal.px'][j][2]
        istol = int(round(10000 * unit_cell.stol((h, k, l))))

        if predict or static:
            # work from a scan static model & assume perfect goniometer
            # FIXME maybe should work back in the option to predict spot positions
            UB = matrix.sqr(experiment.crystal.get_A())
            phi = phi_start + z0 * phi_range
            R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
            RUB = S * R * F * UB
        else:
            # properly compute RUB for every reflection
            UB = matrix.sqr(
                experiment.crystal.get_A_at_scan_point(int(round(z0))))
            phi = phi_start + z0 * phi_range
            R = axis.axis_and_angle_as_r3_rotation_matrix(phi, deg=True)
            RUB = S * R * F * UB

        x = RUB * (h, k, l)
        s = (s0 + x).normalize()

        # can also compute s based on centre of mass of spot
        # s = (origin + x_mm * fast_axis + y_mm * slow_axis).normalize()

        astar = (RUB * (1, 0, 0)).normalize()
        bstar = (RUB * (0, 1, 0)).normalize()
        cstar = (RUB * (0, 0, 1)).normalize()

        ix = beam.dot(astar)
        iy = beam.dot(bstar)
        iz = beam.dot(cstar)

        dx = s.dot(astar)
        dy = s.dot(bstar)
        dz = s.dot(cstar)

        x = x_mm * scl_x
        y = y_mm * scl_y
        z = (z_rad * 180 / math.pi - phi_start) / phi_range

        fout.write('%4d%4d%4d%8.2f%8.2f%4d%8.5f%8.5f%8.5f%8.5f%8.5f%8.5f' % \
                   (h, k, l, I[j], sigI[j], run, ix, dx, iy, dy, iz, dz))
        fout.write('%7.2f%7.2f%8.2f%7.2f%5d\n' % (x, y, z, detector2t, istol))

    fout.close()
    logger.info('Output %d reflections to %s' % (nref, hklout))