Exemplo n.º 1
0
def get_subset_for_symmetry(experiments,
                            reflection_tables,
                            exclude_images=None):
    """Select an image range for symmetry analysis, or just select
    the first 360 degrees of data."""
    refls_for_sym = []
    if exclude_images:
        experiments = exclude_image_ranges_from_scans(reflection_tables,
                                                      experiments,
                                                      exclude_images)
        for refl, exp in zip(reflection_tables, experiments):
            sel = get_selection_for_valid_image_ranges(refl, exp)
            refls_for_sym.append(refl.select(sel))
    else:
        for expt, refl in zip(experiments, reflection_tables):
            sel = get_selection_for_valid_image_ranges(refl, expt)
            if not sel.count(False):
                # Use first 360 degrees if <360 deg i.e. first measured data,
                # but only if no reflections have been exlicitly excluded
                # already
                scan_end = int(
                    math.ceil(360 / abs(expt.scan.get_oscillation()[1])))
                if scan_end < len(expt.scan):
                    sel = refl["xyzobs.px.value"].parts()[2] <= scan_end
            refls_for_sym.append(refl.select(sel))
    return refls_for_sym
Exemplo n.º 2
0
def test_get_selection_for_valid_image_ranges():
    """Test for namesake function"""
    exp = make_scan_experiment()
    exp.scan.set_valid_image_ranges("0", [(2, 10)])
    refl = flex.reflection_table()
    refl["xyzobs.px.value"] = flex.vec3_double([(0, 0, 0.5), (0, 0, 1.5),
                                                (0, 0, 5.5), (0, 0, 9.5),
                                                (0, 0, 10.5)])
    sel = get_selection_for_valid_image_ranges(refl, exp)
    assert list(sel) == [False, True, True, True, False]
    exp = make_scanless_experiment()
    assert list(get_selection_for_valid_image_ranges(refl, exp)) == [True] * 5
Exemplo n.º 3
0
    def __init__(self,
                 experiments,
                 reflections,
                 uuid_cache_in,
                 params=None,
                 do_plot=False,
                 i_plot=None,
                 output_dir=None):
        super(dials_cl_cosym_wrapper, self).__init__(
            events=["run_cosym", "performed_unit_cell_clustering"])
        if params is None:
            params = phil_scope.extract()
        self.params = params

        self._reflections = []
        for refl, expt in zip(reflections, experiments):
            sel = get_selection_for_valid_image_ranges(refl, expt)
            self._reflections.append(refl.select(sel))

        self._experiments, self._reflections = self._filter_min_reflections(
            experiments, self._reflections, uuid_cache_in)
        self.ids_to_identifiers_map = {}
        for table in self._reflections:
            self.ids_to_identifiers_map.update(table.experiment_identifiers())
        self.identifiers_to_ids_map = {
            value: key
            for key, value in self.ids_to_identifiers_map.items()
        }

        if len(self._experiments) > 1:
            # perform unit cell clustering
            identifiers = self._unit_cell_clustering(self._experiments)
            if len(identifiers) < len(self._experiments):
                logger.info(
                    "Selecting subset of %i datasets for cosym analysis: %s" %
                    (len(identifiers), str(identifiers)))
                self._experiments, self._reflections = select_datasets_on_identifiers(
                    self._experiments,
                    self._reflections,
                    use_datasets=identifiers)
                self.uuid_cache = [
                    self.uuid_cache[int(id)] for id in identifiers
                ]

        # Map experiments and reflections to minimum cell
        cb_ops = change_of_basis_ops_to_minimum_cell(
            self._experiments,
            params.lattice_symmetry_max_delta,
            params.relative_length_tolerance,
            params.absolute_angle_tolerance,
        )
        in_cb_ops = len(cb_ops)
        exclude = [
            expt.identifier for expt, cb_op in zip(self._experiments, cb_ops)
            if not cb_op
        ]
        if len(exclude):
            logger.info(
                "Rejecting {} datasets from cosym analysis "\
                "(couldn't determine consistent cb_op to minimum cell):\n"\
                "{}".format(len(exclude), exclude)
            )
            self._experiments, self._reflections = select_datasets_on_identifiers(
                self._experiments, self._reflections, exclude_datasets=exclude)
            cb_ops = list(filter(None, cb_ops))

        ex_cb_ops = len(cb_ops)

        #Normally we expect that all the cb_ops are the same (applicable for PSI with P63)
        assertion_dict = {}
        for cb_op in cb_ops:
            key_ = cb_op.as_hkl()
            assertion_dict[key_] = assertion_dict.get(key_, 0)
            assertion_dict[key_] += 1
        if len(assertion_dict) != 1:
            # unexpected, there is normally only 1 cb operator to minimum cell
            from libtbx.mpi4py import MPI
            mpi_rank = MPI.COMM_WORLD.Get_rank()
            mpi_size = MPI.COMM_WORLD.Get_size()
            print(
                "RANK %02d, # experiments %d, after exclusion %d, unexpectedly there are %d unique cb_ops: %s"
                % (mpi_rank, in_cb_ops, ex_cb_ops, len(assertion_dict),
                   ", ".join([
                       "%s:%d" % (key, assertion_dict[key])
                       for key in assertion_dict
                   ])))
            # revisit with different use cases later

            # In fact we need all cb_ops to match because the user might supply
            # a custom reindexing operator and we need to consistently tranform
            # it from the conventional basis into the minimum basis. Therefore,
            # force them all to match, but make sure user is aware.
            if not params.single_cb_op_to_minimum:
                raise RuntimeError(
                    'There are >1 different cb_ops to minimum and \
cosym.single_cb_op_to_minimum is not True')
            else:
                best_cb_op_str = max(assertion_dict, key=assertion_dict.get)
                best_cb_op = None
                for cb_op in cb_ops:
                    if cb_op.as_hkl() == best_cb_op_str:
                        best_cb_op = cb_op
                        break
                assert best_cb_op is not None
                cb_ops = [best_cb_op] * len(cb_ops)

        self.cb_op_to_minimum = cb_ops

        # Eliminate reflections that are systematically absent due to centring
        # of the lattice, otherwise they would lead to non-integer miller indices
        # when reindexing to a primitive setting
        self._reflections = eliminate_sys_absent(self._experiments,
                                                 self._reflections)

        self._experiments, self._reflections = apply_change_of_basis_ops(
            self._experiments, self._reflections, cb_ops)

        # transform models into miller arrays
        datasets = filtered_arrays_from_experiments_reflections(
            self.experiments,
            self.reflections,
            outlier_rejection_after_filter=False,
            partiality_threshold=params.partiality_threshold,
        )

        datasets = [
            ma.as_anomalous_array().merge_equivalents().array()
            for ma in datasets
        ]

        # opportunity here to subclass as defined above, instead of the dials-implemented version
        self.cosym_analysis = CosymAnalysis(
            datasets,
            self.params,
            do_plot=do_plot,
            i_plot=i_plot,
            plot_fname=self.params.plot.filename,
            plot_format=self.params.plot.format,
            output_dir=output_dir,
            cb_op=cb_ops[0])
Exemplo n.º 4
0
    def __init__(self, experiments, reflections, params=None):
        super(cosym, self).__init__(
            events=["run_cosym", "performed_unit_cell_clustering"])
        if params is None:
            params = phil_scope.extract()
        self.params = params

        self._reflections = []
        for refl, expt in zip(reflections, experiments):
            sel = get_selection_for_valid_image_ranges(refl, expt)
            self._reflections.append(refl.select(sel))

        self._experiments, self._reflections = self._filter_min_reflections(
            experiments, self._reflections)
        self.ids_to_identifiers_map = {}
        for table in self._reflections:
            self.ids_to_identifiers_map.update(table.experiment_identifiers())
        self.identifiers_to_ids_map = {
            value: key
            for key, value in self.ids_to_identifiers_map.items()
        }

        if len(self._experiments) > 1:
            # perform unit cell clustering
            identifiers = self._unit_cell_clustering(self._experiments)
            if len(identifiers) < len(self._experiments):
                logger.info(
                    "Selecting subset of %i datasets for cosym analysis: %s",
                    len(identifiers),
                    str(identifiers),
                )
                self._experiments, self._reflections = select_datasets_on_identifiers(
                    self._experiments,
                    self._reflections,
                    use_datasets=identifiers)

        # Map experiments and reflections to minimum cell
        cb_ops = change_of_basis_ops_to_minimum_cell(
            self._experiments,
            params.lattice_symmetry_max_delta,
            params.relative_length_tolerance,
            params.absolute_angle_tolerance,
        )
        exclude = [
            expt.identifier for expt, cb_op in zip(self._experiments, cb_ops)
            if not cb_op
        ]
        if len(exclude):
            logger.info(
                f"Rejecting {len(exclude)} datasets from cosym analysis "
                f"(couldn't determine consistent cb_op to minimum cell):\n"
                f"{exclude}", )
            self._experiments, self._reflections = select_datasets_on_identifiers(
                self._experiments, self._reflections, exclude_datasets=exclude)
            cb_ops = list(filter(None, cb_ops))

        # Eliminate reflections that are systematically absent due to centring
        # of the lattice, otherwise they would lead to non-integer miller indices
        # when reindexing to a primitive setting
        self._reflections = eliminate_sys_absent(self._experiments,
                                                 self._reflections)

        self._experiments, self._reflections = apply_change_of_basis_ops(
            self._experiments, self._reflections, cb_ops)

        # transform models into miller arrays
        datasets = filtered_arrays_from_experiments_reflections(
            self.experiments,
            self.reflections,
            outlier_rejection_after_filter=False,
            partiality_threshold=params.partiality_threshold,
        )

        datasets = [
            ma.as_anomalous_array().merge_equivalents().array()
            for ma in datasets
        ]
        self.cosym_analysis = CosymAnalysis(datasets, self.params)
Exemplo n.º 5
0
    def __init__(self,
                 experiments,
                 reflections,
                 uuid_cache_in,
                 params=None,
                 do_plot=False,
                 i_plot=None,
                 output_dir=None):
        super(dials_cl_cosym_wrapper, self).__init__(
            events=["run_cosym", "performed_unit_cell_clustering"])
        if params is None:
            params = phil_scope.extract()
        self.params = params

        self._reflections = []
        for refl, expt in zip(reflections, experiments):
            sel = get_selection_for_valid_image_ranges(refl, expt)
            self._reflections.append(refl.select(sel))

        self._experiments, self._reflections = self._filter_min_reflections(
            experiments, self._reflections, uuid_cache_in)
        self.ids_to_identifiers_map = {}
        for table in self._reflections:
            self.ids_to_identifiers_map.update(table.experiment_identifiers())
        self.identifiers_to_ids_map = {
            value: key
            for key, value in self.ids_to_identifiers_map.items()
        }

        if len(self._experiments) > 1:
            # perform unit cell clustering
            identifiers = self._unit_cell_clustering(self._experiments)
            if len(identifiers) < len(self._experiments):
                logger.info(
                    "Selecting subset of %i datasets for cosym analysis: %s" %
                    (len(identifiers), str(identifiers)))
                self._experiments, self._reflections = select_datasets_on_identifiers(
                    self._experiments,
                    self._reflections,
                    use_datasets=identifiers)

        # Map experiments and reflections to minimum cell
        cb_ops = change_of_basis_ops_to_minimum_cell(
            self._experiments,
            params.lattice_symmetry_max_delta,
            params.relative_length_tolerance,
            params.absolute_angle_tolerance,
        )
        exclude = [
            expt.identifier for expt, cb_op in zip(self._experiments, cb_ops)
            if not cb_op
        ]
        if len(exclude):
            logger.info(
                "Rejecting {} datasets from cosym analysis "\
                "(couldn't determine consistent cb_op to minimum cell):\n"\
                "{}".format(len(exclude), exclude)
            )
            self._experiments, self._reflections = select_datasets_on_identifiers(
                self._experiments, self._reflections, exclude_datasets=exclude)
            cb_ops = list(filter(None, cb_ops))

        # Eliminate reflections that are systematically absent due to centring
        # of the lattice, otherwise they would lead to non-integer miller indices
        # when reindexing to a primitive setting
        self._reflections = eliminate_sys_absent(self._experiments,
                                                 self._reflections)

        self._experiments, self._reflections = apply_change_of_basis_ops(
            self._experiments, self._reflections, cb_ops)

        # transform models into miller arrays
        datasets = filtered_arrays_from_experiments_reflections(
            self.experiments,
            self.reflections,
            outlier_rejection_after_filter=False,
            partiality_threshold=params.partiality_threshold,
        )

        datasets = [
            ma.as_anomalous_array().merge_equivalents().array()
            for ma in datasets
        ]

        # opportunity here to subclass as defined above, instead of the dials-implemented version
        self.cosym_analysis = CosymAnalysis(
            datasets,
            self.params,
            do_plot=do_plot,
            i_plot=i_plot,
            plot_fname=self.params.plot.filename,
            plot_format=self.params.plot.format,
            output_dir=output_dir)
        #Fixed in subclass: parent class apparently erases the knowledge of input-to-minimum cb_ops.
        # without storing the op in self, we can never trace back to input setting.
        self.cb_op_to_minimum = cb_ops

        #Not sure yet, we may be assuming that all the cb_ops are the same (applicable for PSI with P63)
        assertion_set = set(cb_ops)
        assert len(
            assertion_set
        ) == 1  # guarantees all are the same; revisit with different use cases later