示例#1
0
def test_ModelEvaluation(dials_regression, tmpdir):
    # thaumatin
    data_dir = os.path.join(dials_regression, "indexing_test_data",
                            "i04_weak_data")
    pickle_path = os.path.join(data_dir, "full.pickle")
    sweep_path = os.path.join(data_dir, "experiments_import.json")

    input_reflections = flex.reflection_table.from_file(pickle_path)
    input_experiments = load.experiment_list(sweep_path, check_format=False)

    input_reflections = input_reflections.select(
        input_reflections["xyzobs.px.value"].parts()[2] < 100)
    input_reflections.centroid_px_to_mm(input_experiments[0].detector,
                                        scan=input_experiments[0].scan)
    input_reflections.map_centroids_to_reciprocal_space(
        input_experiments[0].detector,
        input_experiments[0].beam,
        goniometer=input_experiments[0].goniometer,
    )
    input_reflections["imageset_id"] = flex.size_t(input_reflections.size(), 0)
    input_reflections["id"] = flex.int(input_reflections.size(), -1)

    refine_params = refine_phil.fetch().extract()
    evaluator = model_evaluation.ModelEvaluation(
        refinement_params=refine_params)

    experiments = copy.deepcopy(input_experiments)
    reflections = copy.deepcopy(input_reflections)
    experiments[0].crystal = Crystal.from_dict(
        dict([
            ("__id__", "crystal"),
            (
                "real_space_a",
                (20.007058080503633, 49.721143642677994, 16.636052132572846),
            ),
            (
                "real_space_b",
                (-15.182202482876685, 24.93846318493148, -50.7116866438356),
            ),
            (
                "real_space_c",
                (-135.23051191036296, 41.14539066294313, 55.41374425160883),
            ),
            ("space_group_hall_symbol", " P 1"),
        ]))

    assign_indices = AssignIndicesGlobal()
    assign_indices(reflections, experiments)
    result = evaluator.evaluate(experiments, reflections)
    assert result is not None
    assert result.n_indexed == 7313
    assert result.fraction_indexed == pytest.approx(0.341155066244)
    assert result.rmsds == pytest.approx(
        (0.10215787570953785, 0.12954412140128563, 0.0010980583382102509))
示例#2
0
    def choose_best_orientation_matrix(self, candidate_orientation_matrices):

        from dials.algorithms.indexing import model_evaluation

        solution_scorer = self.params.basis_vector_combinations.solution_scorer
        if solution_scorer == "weighted":
            weighted_params = self.params.basis_vector_combinations.weighted
            solutions = model_evaluation.ModelRankWeighted(
                power=weighted_params.power,
                volume_weight=weighted_params.volume_weight,
                n_indexed_weight=weighted_params.n_indexed_weight,
                rmsd_weight=weighted_params.rmsd_weight,
            )
        else:
            filter_params = self.params.basis_vector_combinations.filter
            solutions = model_evaluation.ModelRankFilter(
                check_doubled_cell=filter_params.check_doubled_cell,
                likelihood_cutoff=filter_params.likelihood_cutoff,
                volume_cutoff=filter_params.volume_cutoff,
                n_indexed_cutoff=filter_params.n_indexed_cutoff,
            )

        args = []

        for cm in candidate_orientation_matrices:
            sel = self.reflections["id"] == -1
            if self.d_min is not None:
                sel &= 1 / self.reflections["rlp"].norms() > self.d_min
            xo, yo, zo = self.reflections["xyzobs.mm.value"].parts()
            imageset_id = self.reflections["imageset_id"]
            experiments = ExperimentList()
            for i_expt, expt in enumerate(self.experiments):
                # XXX Not sure if we still need this loop over self.experiments
                if expt.scan is not None:
                    start, end = expt.scan.get_oscillation_range()
                    if (end - start) > 360:
                        # only use reflections from the first 360 degrees of the scan
                        sel.set_selected(
                            (imageset_id == i_expt)
                            & (zo > ((start * math.pi / 180) + 2 * math.pi)),
                            False,
                        )
                experiments.append(
                    Experiment(
                        imageset=expt.imageset,
                        beam=expt.beam,
                        detector=expt.detector,
                        goniometer=expt.goniometer,
                        scan=expt.scan,
                        crystal=cm,
                    )
                )
            refl = self.reflections.select(sel)
            self.index_reflections(experiments, refl)
            if refl.get_flags(refl.flags.indexed).count(True) == 0:
                continue

            from rstbx.dps_core.cell_assessment import SmallUnitCellVolume

            from dials.algorithms.indexing import non_primitive_basis

            threshold = self.params.basis_vector_combinations.sys_absent_threshold
            if threshold and (
                self._symmetry_handler.target_symmetry_primitive is None
                or self._symmetry_handler.target_symmetry_primitive.unit_cell() is None
            ):
                try:
                    non_primitive_basis.correct(
                        experiments, refl, self._assign_indices, threshold
                    )
                    if refl.get_flags(refl.flags.indexed).count(True) == 0:
                        continue
                except SmallUnitCellVolume:
                    logger.debug(
                        "correct_non_primitive_basis SmallUnitCellVolume error for unit cell %s:",
                        experiments[0].crystal.get_unit_cell(),
                    )
                    continue
                except RuntimeError as e:
                    if "Krivy-Gruber iteration limit exceeded" in str(e):
                        logger.debug(
                            "correct_non_primitive_basis Krivy-Gruber iteration limit exceeded error for unit cell %s:",
                            experiments[0].crystal.get_unit_cell(),
                        )
                        continue
                    raise
                if (
                    experiments[0].crystal.get_unit_cell().volume()
                    < self.params.min_cell_volume
                ):
                    continue

            if self.params.known_symmetry.space_group is not None:
                new_crystal, _ = self._symmetry_handler.apply_symmetry(
                    experiments[0].crystal
                )
                if new_crystal is None:
                    continue
                experiments[0].crystal.update(new_crystal)

            args.append((experiments, refl))
            if len(args) == self.params.basis_vector_combinations.max_refine:
                break

        from libtbx import easy_mp

        evaluator = model_evaluation.ModelEvaluation(self.all_params)
        results = easy_mp.parallel_map(
            evaluator.evaluate,
            args,
            iterable_type=easy_mp.posiargs,
            processes=self.params.nproc,
            preserve_exception_message=True,
        )

        for soln in results:
            if soln is None:
                continue
            solutions.append(soln)

        if len(solutions):
            logger.info("Candidate solutions:")
            logger.info(str(solutions))
            best_model = solutions.best_model()
            logger.debug("best model_likelihood: %.2f", best_model.model_likelihood)
            logger.debug("best n_indexed: %i", best_model.n_indexed)
            self.hkl_offset = best_model.hkl_offset
            return best_model.crystal, best_model.n_indexed
        else:
            return None, None