Click here to go to the corresponding page for the latest version of DIALS
Source code for dials.algorithms.indexing.real_space_grid_search
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; indent-tabs-mode: nil; python-indent: 2 -*-
#
# dials.algorithms.indexing.real_space_grid_search.py
#
# Copyright (C) 2014 Diamond Light Source
#
# Author: Richard Gildea
#
# This code is distributed under the BSD license, a copy of which is
# included in the root directory of this package.
from __future__ import absolute_import, division
from __future__ import print_function
import math
import logging
logger = logging.getLogger(__name__)
from scitbx import matrix
from scitbx.array_family import flex
from dials.algorithms.indexing.indexer import indexer_base, optimise_basis_vectors
from dials.algorithms.indexing.indexer import is_approximate_integer_multiple
from dxtbx.model.experiment_list import Experiment, ExperimentList
[docs]class indexer_real_space_grid_search(indexer_base):
def __init__(self, reflections, imagesets, params):
super(indexer_real_space_grid_search, self).__init__(
reflections, imagesets, params
)
[docs] def find_lattices(self):
self.real_space_grid_search()
crystal_models = self.candidate_crystal_models
experiments = ExperimentList()
for cm in crystal_models:
for imageset in self.imagesets:
experiments.append(
Experiment(
imageset=imageset,
beam=imageset.get_beam(),
detector=imageset.get_detector(),
goniometer=imageset.get_goniometer(),
scan=imageset.get_scan(),
crystal=cm,
)
)
return experiments
[docs] def real_space_grid_search(self):
d_min = self.params.refinement_protocol.d_min_start
sel = self.reflections["id"] == -1
if d_min is not None:
sel &= 1 / self.reflections["rlp"].norms() > d_min
reciprocal_lattice_points = self.reflections["rlp"].select(sel)
logger.info("Indexing from %i reflections" % len(reciprocal_lattice_points))
def compute_functional(vector):
two_pi_S_dot_v = 2 * math.pi * reciprocal_lattice_points.dot(vector)
return flex.sum(flex.cos(two_pi_S_dot_v))
from rstbx.array_family import flex
from rstbx.dps_core import SimpleSamplerTool
assert self.target_symmetry_primitive is not None
assert self.target_symmetry_primitive.unit_cell() is not None
SST = SimpleSamplerTool(self.params.real_space_grid_search.characteristic_grid)
SST.construct_hemisphere_grid(SST.incr)
cell_dimensions = self.target_symmetry_primitive.unit_cell().parameters()[:3]
unique_cell_dimensions = set(cell_dimensions)
logger.info(
"Number of search vectors: %i"
% (len(SST.angles) * len(unique_cell_dimensions))
)
vectors = flex.vec3_double()
function_values = flex.double()
for i, direction in enumerate(SST.angles):
for l in unique_cell_dimensions:
v = matrix.col(direction.dvec) * l
f = compute_functional(v.elems)
vectors.append(v.elems)
function_values.append(f)
perm = flex.sort_permutation(function_values, reverse=True)
vectors = vectors.select(perm)
function_values = function_values.select(perm)
unique_vectors = []
i = 0
while len(unique_vectors) < 30:
v = matrix.col(vectors[i])
is_unique = True
if i > 0:
for v_u in unique_vectors:
if v.length() < v_u.length():
if is_approximate_integer_multiple(v, v_u):
is_unique = False
break
elif is_approximate_integer_multiple(v_u, v):
is_unique = False
break
if is_unique:
unique_vectors.append(v)
i += 1
for i in range(30):
v = matrix.col(vectors[i])
logger.debug(
"%s %s %s" % (str(v.elems), str(v.length()), str(function_values[i]))
)
basis_vectors = [v.elems for v in unique_vectors]
self.candidate_basis_vectors = basis_vectors
if self.params.optimise_initial_basis_vectors:
optimised_basis_vectors = optimise_basis_vectors(
reciprocal_lattice_points, basis_vectors
)
optimised_function_values = flex.double(
[compute_functional(v) for v in optimised_basis_vectors]
)
perm = flex.sort_permutation(optimised_function_values, reverse=True)
optimised_basis_vectors = optimised_basis_vectors.select(perm)
optimised_function_values = optimised_function_values.select(perm)
unique_vectors = [matrix.col(v) for v in optimised_basis_vectors]
logger.info("Number of unique vectors: %i" % len(unique_vectors))
for i in range(len(unique_vectors)):
logger.debug(
"%s %s %s"
% (
str(compute_functional(unique_vectors[i].elems)),
str(unique_vectors[i].length()),
str(unique_vectors[i].elems),
)
)
crystal_models = []
self.candidate_basis_vectors = unique_vectors
self.debug_show_candidate_basis_vectors()
if self.params.debug_plots:
self.debug_plot_candidate_basis_vectors()
candidate_orientation_matrices = self.find_candidate_orientation_matrices(
unique_vectors
)
crystal_model, n_indexed = self.choose_best_orientation_matrix(
candidate_orientation_matrices
)
if crystal_model is not None:
crystal_models = [crystal_model]
else:
crystal_models = []
# assert len(crystal_models) > 0
candidate_orientation_matrices = crystal_models
# for i in range(len(candidate_orientation_matrices)):
# if self.target_symmetry_primitive is not None:
##print "symmetrizing model"
##self.target_symmetry_primitive.show_summary()
# symmetrized_model = self.apply_symmetry(
# candidate_orientation_matrices[i], self.target_symmetry_primitive)
# candidate_orientation_matrices[i] = symmetrized_model
self.candidate_crystal_models = candidate_orientation_matrices