コード例 #1
0
ファイル: index_strong.py プロジェクト: dials/dials_scratch
  def run(self):
    ''' Parse the options. '''
    from dials.util.options import flatten_experiments, flatten_reflections
    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)
    self.params = params
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    assert len(reflections) == len(experiments) == 1
    reflections = reflections[0]
    exp = experiments[0]

    from dials.algorithms.indexing import index_reflections
    from dials.algorithms.indexing.indexer import indexer_base

    reflections['id'] = flex.int(len(reflections), -1)
    reflections['imageset_id'] = flex.int(len(reflections), 0)
    reflections = indexer_base.map_spots_pixel_to_mm_rad(reflections, exp.detector, exp.scan)

    indexer_base.map_centroids_to_reciprocal_space(
      reflections, exp.detector, exp.beam, exp.goniometer,)

    index_reflections(reflections,
                      experiments, params.d_min,
                      tolerance=0.3)
    indexed_reflections = reflections.select(reflections['miller_index'] != (0,0,0))
    print "Indexed %d reflections out of %d"%(len(indexed_reflections), len(reflections))
    easy_pickle.dump("indexedstrong.pickle", indexed_reflections)
コード例 #2
0
    def run(self):
        """Parse the options."""
        from dials.util.options import flatten_experiments, flatten_reflections

        # Parse the command line arguments
        params, options = self.parser.parse_args(show_diff_phil=True)
        self.params = params
        experiments = flatten_experiments(params.input.experiments)
        reflections = flatten_reflections(params.input.reflections)

        assert len(reflections) == len(experiments) == 1
        reflections = reflections[0]
        exp = experiments[0]

        from dials.algorithms.indexing import index_reflections
        from dials.algorithms.indexing.indexer import Indexer

        reflections["id"] = flex.int(len(reflections), -1)
        reflections["imageset_id"] = flex.int(len(reflections), 0)
        reflections = Indexer.map_spots_pixel_to_mm_rad(
            reflections, exp.detector, exp.scan)

        Indexer.map_centroids_to_reciprocal_space(reflections, exp.detector,
                                                  exp.beam, exp.goniometer)

        index_reflections(reflections,
                          experiments,
                          params.d_min,
                          tolerance=0.3)
        indexed_reflections = reflections.select(
            reflections["miller_index"] != (0, 0, 0))
        print("Indexed %d reflections out of %d" %
              (len(indexed_reflections), len(reflections)))
        easy_pickle.dump("indexedstrong.pickle", indexed_reflections)
コード例 #3
0
    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()
コード例 #4
0
def test_index_reflections(dials_regression):
    experiments_json = os.path.join(dials_regression, "indexing_test_data",
                                    "i04_weak_data", "experiments.json")
    experiments = load.experiment_list(experiments_json, check_format=False)
    reflections = flex.reflection_table.from_file(
        os.path.join(dials_regression, "indexing_test_data", "i04_weak_data",
                     "full.pickle"))
    reflections.centroid_px_to_mm(experiments)
    reflections.map_centroids_to_reciprocal_space(experiments)
    reflections["imageset_id"] = flex.int(len(reflections), 0)
    reflections["id"] = flex.int(len(reflections), -1)
    with pytest.deprecated_call():
        index_reflections(reflections, experiments)
    assert "miller_index" in reflections
    counts = reflections["id"].counts()
    assert dict(counts) == {-1: 1390, 0: 114692}
コード例 #5
0
    def __init__(self, experiment, reflections, expected_miller_indices):

        from dials.algorithms.indexing \
             import index_reflections, index_reflections_local
        import copy

        # index reflections using simple "global" method
        self.reflections_global = copy.deepcopy(reflections)
        self.reflections_global['id'] = flex.int(len(self.reflections_global),
                                                 -1)
        self.reflections_global['imageset_id'] = flex.int(
            len(self.reflections_global), 0)
        index_reflections(self.reflections_global,
                          ExperimentList([experiment]))
        non_zero_sel = (self.reflections_global['miller_index'] != (0, 0, 0))
        assert self.reflections_global['id'].select(~non_zero_sel).all_eq(-1)
        self.misindexed_global = (
            expected_miller_indices == self.reflections_global['miller_index']
        ).select(non_zero_sel).count(False)
        self.correct_global = (expected_miller_indices == self.
                               reflections_global['miller_index']).count(True)

        # index reflections using xds-style "local" method
        self.reflections_local = copy.deepcopy(reflections)
        self.reflections_local['id'] = flex.int(len(self.reflections_local),
                                                -1)
        index_reflections_local(self.reflections_local,
                                ExperimentList([experiment]))
        non_zero_sel = (self.reflections_local['miller_index'] != (0, 0, 0))
        assert self.reflections_local['id'].select(~non_zero_sel).all_eq(-1)
        self.misindexed_local = (
            expected_miller_indices == self.reflections_local['miller_index']
        ).select(non_zero_sel).count(False)
        self.correct_local = (expected_miller_indices == self.
                              reflections_local['miller_index']).count(True)

        print self.misindexed_global, self.correct_global, len(
            self.reflections_global)
        print self.misindexed_local, self.correct_local, len(
            self.reflections_local)
コード例 #6
0
  def __init__(self, experiment, reflections,
               expected_miller_indices):

    from dials.algorithms.indexing \
         import index_reflections, index_reflections_local
    import copy

    # index reflections using simple "global" method
    self.reflections_global = copy.deepcopy(reflections)
    self.reflections_global['id'] = flex.int(len(self.reflections_global), -1)
    self.reflections_global['imageset_id'] = flex.int(len(self.reflections_global), 0)
    index_reflections(
      self.reflections_global, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_global['miller_index'] != (0,0,0))
    assert self.reflections_global['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_global = (
      expected_miller_indices == self.reflections_global['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_global = (
      expected_miller_indices == self.reflections_global['miller_index']).count(True)


    # index reflections using xds-style "local" method
    self.reflections_local = copy.deepcopy(reflections)
    self.reflections_local['id'] = flex.int(len(self.reflections_local), -1)
    index_reflections_local(
      self.reflections_local, ExperimentList([experiment]))
    non_zero_sel = (self.reflections_local['miller_index'] != (0,0,0))
    assert self.reflections_local['id'].select(~non_zero_sel).all_eq(-1)
    self.misindexed_local = (
      expected_miller_indices == self.reflections_local['miller_index']).select(
        non_zero_sel).count(False)
    self.correct_local = (
      expected_miller_indices == self.reflections_local['miller_index']).count(True)

    print self.misindexed_global, self.correct_global, len(self.reflections_global)
    print self.misindexed_local, self.correct_local, len(self.reflections_local)
コード例 #7
0
ファイル: reindex.py プロジェクト: biochem-fan/dials
def run(args):
    import libtbx.load_env
    from libtbx.utils import Sorry

    usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_reflections=True,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(show_diff_phil=True)

    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0 and len(reflections) == 0:
        parser.print_help()
        return
    elif len(experiments.crystals()) > 1:
        raise Sorry("Only one crystal can be processed at a time")
    if params.change_of_basis_op is None:
        raise Sorry("Please provide a change_of_basis_op.")

    reference_crystal = None
    if params.reference is not None:
        from dxtbx.serialize import load

        reference_experiments = load.experiment_list(params.reference, check_format=False)
        assert len(reference_experiments.crystals()) == 1
        reference_crystal = reference_experiments.crystals()[0]

    if len(experiments) and params.change_of_basis_op is libtbx.Auto:
        if reference_crystal is not None:
            from dials.algorithms.indexing.compare_orientation_matrices import (
                difference_rotation_matrix_and_euler_angles,
            )

            cryst = experiments.crystals()[0]
            R, euler_angles, change_of_basis_op = difference_rotation_matrix_and_euler_angles(cryst, reference_crystal)
            print "Change of basis op: %s" % change_of_basis_op
            print "Rotation matrix to transform input crystal to reference::"
            print R.mathematica_form(format="%.3f", one_row_per_line=True)
            print "Euler angles (xyz): %.2f, %.2f, %.2f" % euler_angles

        elif len(reflections):
            assert len(reflections) == 1

            # always re-map reflections to reciprocal space
            from dials.algorithms.indexing import indexer

            refl_copy = flex.reflection_table()
            for i, imageset in enumerate(experiments.imagesets()):
                if "imageset_id" in reflections[0]:
                    sel = reflections[0]["imageset_id"] == i
                else:
                    sel = reflections[0]["id"] == i
                refl = indexer.indexer_base.map_spots_pixel_to_mm_rad(
                    reflections[0].select(sel), imageset.get_detector(), imageset.get_scan()
                )

                indexer.indexer_base.map_centroids_to_reciprocal_space(
                    refl, imageset.get_detector(), imageset.get_beam(), imageset.get_goniometer()
                )
                refl_copy.extend(refl)

            # index the reflection list using the input experiments list
            refl_copy["id"] = flex.int(len(refl_copy), -1)
            from dials.algorithms.indexing import index_reflections

            index_reflections(refl_copy, experiments, tolerance=0.2)
            hkl_expt = refl_copy["miller_index"]
            hkl_input = reflections[0]["miller_index"]

            change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt)

            # reset experiments list since we don't want to reindex this
            experiments = []

    else:
        change_of_basis_op = sgtbx.change_of_basis_op(params.change_of_basis_op)

    if len(experiments):
        experiment = experiments[0]
        cryst_orig = copy.deepcopy(experiment.crystal)
        cryst_reindexed = cryst_orig.change_basis(change_of_basis_op)
        if params.space_group is not None:
            a, b, c = cryst_reindexed.get_real_space_vectors()
            cryst_reindexed = crystal_model(a, b, c, space_group=params.space_group.group())
        experiment.crystal.update(cryst_reindexed)

        print "Old crystal:"
        print cryst_orig
        print
        print "New crystal:"
        print cryst_reindexed
        print

        print "Saving reindexed experimental models to %s" % params.output.experiments
        dump.experiment_list(experiments, params.output.experiments)

    if len(reflections):
        assert len(reflections) == 1
        reflections = reflections[0]

        miller_indices = reflections["miller_index"]

        if params.hkl_offset is not None:
            h, k, l = miller_indices.as_vec3_double().parts()
            h += params.hkl_offset[0]
            k += params.hkl_offset[1]
            l += params.hkl_offset[2]
            miller_indices = flex.miller_index(h.iround(), k.iround(), l.iround())
        non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(miller_indices)
        if non_integral_indices.size() > 0:
            print "Removing %i/%i reflections (change of basis results in non-integral indices)" % (
                non_integral_indices.size(),
                miller_indices.size(),
            )
        sel = flex.bool(miller_indices.size(), True)
        sel.set_selected(non_integral_indices, False)
        miller_indices_reindexed = change_of_basis_op.apply(miller_indices.select(sel))
        reflections["miller_index"].set_selected(sel, miller_indices_reindexed)
        reflections["miller_index"].set_selected(~sel, (0, 0, 0))

        print "Saving reindexed reflections to %s" % params.output.reflections
        easy_pickle.dump(params.output.reflections, reflections)
コード例 #8
0
def run(args):
    import libtbx.load_env
    from libtbx.utils import Sorry
    usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_reflections=True,
                          read_experiments=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)

    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0 and len(reflections) == 0:
        parser.print_help()
        return
    if params.change_of_basis_op is None:
        raise Sorry("Please provide a change_of_basis_op.")

    reference_crystal = None
    if params.reference is not None:
        from dxtbx.serialize import load
        reference_experiments = load.experiment_list(params.reference,
                                                     check_format=False)
        assert len(reference_experiments.crystals()) == 1
        reference_crystal = reference_experiments.crystals()[0]

    if len(experiments) and params.change_of_basis_op is libtbx.Auto:
        if reference_crystal is not None:
            if len(experiments.crystals()) > 1:
                raise Sorry("Only one crystal can be processed at a time")
            from dials.algorithms.indexing.compare_orientation_matrices \
                 import difference_rotation_matrix_axis_angle

            cryst = experiments.crystals()[0]
            R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle(
                cryst, reference_crystal)
            print("Change of basis op: %s" % change_of_basis_op)
            print("Rotation matrix to transform input crystal to reference::")
            print(R.mathematica_form(format="%.3f", one_row_per_line=True))
            print("Rotation of %.3f degrees" % angle,
                  "about axis (%.3f, %.3f, %.3f)" % axis)

        elif len(reflections):
            assert len(reflections) == 1

            # always re-map reflections to reciprocal space
            from dials.algorithms.indexing import indexer
            refl_copy = flex.reflection_table()
            for i, imageset in enumerate(experiments.imagesets()):
                if 'imageset_id' in reflections[0]:
                    sel = (reflections[0]['imageset_id'] == i)
                else:
                    sel = (reflections[0]['id'] == i)
                refl = indexer.indexer_base.map_spots_pixel_to_mm_rad(
                    reflections[0].select(sel), imageset.get_detector(),
                    imageset.get_scan())

                indexer.indexer_base.map_centroids_to_reciprocal_space(
                    refl, imageset.get_detector(), imageset.get_beam(),
                    imageset.get_goniometer())
                refl_copy.extend(refl)

            # index the reflection list using the input experiments list
            refl_copy['id'] = flex.int(len(refl_copy), -1)
            from dials.algorithms.indexing import index_reflections
            index_reflections(refl_copy, experiments, tolerance=0.2)
            hkl_expt = refl_copy['miller_index']
            hkl_input = reflections[0]['miller_index']

            change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt)

            # reset experiments list since we don't want to reindex this
            experiments = []

    else:
        change_of_basis_op = sgtbx.change_of_basis_op(
            params.change_of_basis_op)

    if len(experiments):
        for crystal in experiments.crystals():
            cryst_orig = copy.deepcopy(crystal)
            cryst_reindexed = cryst_orig.change_basis(change_of_basis_op)
            if params.space_group is not None:
                a, b, c = cryst_reindexed.get_real_space_vectors()
                cryst_reindexed = Crystal(
                    a, b, c, space_group=params.space_group.group())
            crystal.update(cryst_reindexed)

            print("Old crystal:")
            print(cryst_orig)
            print()
            print("New crystal:")
            print(cryst_reindexed)
            print()

        print("Saving reindexed experimental models to %s" %
              params.output.experiments)
        dump.experiment_list(experiments, params.output.experiments)

    if len(reflections):
        assert (len(reflections) == 1)
        reflections = reflections[0]

        miller_indices = reflections['miller_index']

        if params.hkl_offset is not None:
            h, k, l = miller_indices.as_vec3_double().parts()
            h += params.hkl_offset[0]
            k += params.hkl_offset[1]
            l += params.hkl_offset[2]
            miller_indices = flex.miller_index(h.iround(), k.iround(),
                                               l.iround())
        non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(
            miller_indices)
        if non_integral_indices.size() > 0:
            print(
                "Removing %i/%i reflections (change of basis results in non-integral indices)"
                % (non_integral_indices.size(), miller_indices.size()))
        sel = flex.bool(miller_indices.size(), True)
        sel.set_selected(non_integral_indices, False)
        miller_indices_reindexed = change_of_basis_op.apply(
            miller_indices.select(sel))
        reflections['miller_index'].set_selected(sel, miller_indices_reindexed)
        reflections['miller_index'].set_selected(~sel, (0, 0, 0))

        print("Saving reindexed reflections to %s" % params.output.reflections)
        easy_pickle.dump(params.output.reflections, reflections)
コード例 #9
0
def run(args):
    import libtbx.load_env
    from dials.util import Sorry

    usage = "dials.reindex [options] indexed.expt indexed.refl"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_reflections=True,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(show_diff_phil=True)

    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0 and len(reflections) == 0:
        parser.print_help()
        return
    if params.change_of_basis_op is None:
        raise Sorry("Please provide a change_of_basis_op.")

    reference_crystal = None
    if params.reference.experiments is not None:
        from dxtbx.serialize import load

        reference_experiments = load.experiment_list(
            params.reference.experiments, check_format=False)
        assert len(reference_experiments.crystals()) == 1
        reference_crystal = reference_experiments.crystals()[0]

    if params.reference.reflections is not None:
        # First check that we have everything as expected for the reference reindexing
        # Currently only supports reindexing one dataset at a time
        if params.reference.experiments is None:
            raise Sorry(
                """For reindexing against a reference dataset, a reference
experiments file must also be specified with the option: reference= """)
        if not os.path.exists(params.reference.reflections):
            raise Sorry("Could not locate reference dataset reflection file")
        if len(experiments) != 1 or len(reflections) != 1:
            raise Sorry(
                "Only one dataset can be reindexed to a reference at a time")

        reference_reflections = flex.reflection_table().from_file(
            params.reference.reflections)

        test_reflections = reflections[0]

        if (reference_crystal.get_space_group().type().number() !=
                experiments.crystals()[0].get_space_group().type().number()):
            raise Sorry("Space group of input does not match reference")

        # Set some flags to allow filtering, if wanting to reindex against
        # reference with data that has not yet been through integration
        if (test_reflections.get_flags(
                test_reflections.flags.integrated_sum).count(True) == 0):
            assert (
                "intensity.sum.value"
                in test_reflections), "No 'intensity.sum.value' in reflections"
            test_reflections.set_flags(
                flex.bool(test_reflections.size(), True),
                test_reflections.flags.integrated_sum,
            )
        if (reference_reflections.get_flags(
                reference_reflections.flags.integrated_sum).count(True) == 0):
            assert ("intensity.sum.value" in test_reflections
                    ), "No 'intensity.sum.value in reference reflections"
            reference_reflections.set_flags(
                flex.bool(reference_reflections.size(), True),
                reference_reflections.flags.integrated_sum,
            )

        # Make miller array of the two datasets
        try:
            test_miller_set = filtered_arrays_from_experiments_reflections(
                experiments, [test_reflections])[0]
        except ValueError:
            raise Sorry(
                "No reflections remain after filtering the test dataset")
        try:
            reference_miller_set = filtered_arrays_from_experiments_reflections(
                reference_experiments, [reference_reflections])[0]
        except ValueError:
            raise Sorry(
                "No reflections remain after filtering the reference dataset")

        from dials.algorithms.symmetry.reindex_to_reference import (
            determine_reindex_operator_against_reference, )

        change_of_basis_op = determine_reindex_operator_against_reference(
            test_miller_set, reference_miller_set)

    elif len(experiments) and params.change_of_basis_op is libtbx.Auto:
        if reference_crystal is not None:
            if len(experiments.crystals()) > 1:
                raise Sorry("Only one crystal can be processed at a time")
            from dials.algorithms.indexing.compare_orientation_matrices import (
                difference_rotation_matrix_axis_angle, )

            cryst = experiments.crystals()[0]
            R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle(
                cryst, reference_crystal)
            print("Change of basis op: %s" % change_of_basis_op)
            print("Rotation matrix to transform input crystal to reference::")
            print(R.mathematica_form(format="%.3f", one_row_per_line=True))
            print(
                "Rotation of %.3f degrees" % angle,
                "about axis (%.3f, %.3f, %.3f)" % axis,
            )

        elif len(reflections):
            assert len(reflections) == 1

            # always re-map reflections to reciprocal space
            refl_copy = flex.reflection_table()
            for i, imageset in enumerate(experiments.imagesets()):
                if "imageset_id" in reflections[0]:
                    sel = reflections[0]["imageset_id"] == i
                else:
                    sel = reflections[0]["id"] == i
                refl = reflections[0].select(sel)
                refl.centroid_px_to_mm(imageset.get_detector(),
                                       imageset.get_scan())
                refl.map_centroids_to_reciprocal_space(
                    imageset.get_detector(),
                    imageset.get_beam(),
                    imageset.get_goniometer(),
                )
                refl_copy.extend(refl)

            # index the reflection list using the input experiments list
            refl_copy["id"] = flex.int(len(refl_copy), -1)
            from dials.algorithms.indexing import index_reflections

            index_reflections(refl_copy, experiments, tolerance=0.2)
            hkl_expt = refl_copy["miller_index"]
            hkl_input = reflections[0]["miller_index"]

            change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt)

            # reset experiments list since we don't want to reindex this
            experiments = []

    else:
        change_of_basis_op = sgtbx.change_of_basis_op(
            params.change_of_basis_op)

    if len(experiments):
        for crystal in experiments.crystals():
            cryst_orig = copy.deepcopy(crystal)
            cryst_reindexed = cryst_orig.change_basis(change_of_basis_op)
            if params.space_group is not None:
                a, b, c = cryst_reindexed.get_real_space_vectors()
                A_varying = [
                    cryst_reindexed.get_A_at_scan_point(i)
                    for i in range(cryst_reindexed.num_scan_points)
                ]
                cryst_reindexed = Crystal(
                    a, b, c, space_group=params.space_group.group())
                cryst_reindexed.set_A_at_scan_points(A_varying)
            crystal.update(cryst_reindexed)

            print("Old crystal:")
            print(cryst_orig)
            print()
            print("New crystal:")
            print(cryst_reindexed)
            print()

        print("Saving reindexed experimental models to %s" %
              params.output.experiments)
        dump.experiment_list(experiments, params.output.experiments)

    if len(reflections):
        assert len(reflections) == 1
        reflections = reflections[0]

        miller_indices = reflections["miller_index"]

        if params.hkl_offset is not None:
            h, k, l = miller_indices.as_vec3_double().parts()
            h += params.hkl_offset[0]
            k += params.hkl_offset[1]
            l += params.hkl_offset[2]
            miller_indices = flex.miller_index(h.iround(), k.iround(),
                                               l.iround())
        non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(
            miller_indices)
        if non_integral_indices.size() > 0:
            print(
                "Removing %i/%i reflections (change of basis results in non-integral indices)"
                % (non_integral_indices.size(), miller_indices.size()))
        sel = flex.bool(miller_indices.size(), True)
        sel.set_selected(non_integral_indices, False)
        miller_indices_reindexed = change_of_basis_op.apply(
            miller_indices.select(sel))
        reflections["miller_index"].set_selected(sel, miller_indices_reindexed)
        reflections["miller_index"].set_selected(~sel, (0, 0, 0))

        print("Saving reindexed reflections to %s" % params.output.reflections)
        easy_pickle.dump(params.output.reflections, reflections)