Source code for dials.algorithms.refinement.weighting_strategies

"""Contains classes used to provide weighting schemes as strategies for
ReflectionManagers."""

from dials.algorithms.refinement import DialsRefineConfigError
from dials.array_family import flex


[docs]class StatisticalWeightingStrategy: """Defines a single method that provides a ReflectionManager with a strategy for calculating weights for refinement"""
[docs] @staticmethod def calculate_weights(reflections): """set 'statistical weights', that is w(x) = 1/var(x)""" weights = (reflections["xyzobs.mm.variance"]).deep_copy() parts = weights.parts() for w in parts: sel = w > 0.0 w.set_selected(sel, 1.0 / w.select(sel)) reflections["xyzobs.mm.weights"] = flex.vec3_double(*parts) indexed = reflections.select(reflections.get_flags(reflections.flags.indexed)) if any(indexed["xyzobs.mm.weights"].norms() == 0.0): raise DialsRefineConfigError( "Cannot set statistical weights as some indexed reflections have observed variances equal to zero" ) return reflections
[docs]class StillsWeightingStrategy(StatisticalWeightingStrategy): """Defines a single method that provides a ReflectionManager with a strategy for calculating weights for refinement. This version uses statistical weights for X and Y and a fixed constant for the delta Psi part, defaulting to 1000000"""
[docs] def __init__(self, delpsi_constant=1000000): self._delpsi_constant = delpsi_constant
[docs] def calculate_weights(self, reflections): """Include weights for DeltaPsi""" # call parent class method to set X and Y weights reflections = super().calculate_weights(reflections) reflections["delpsical.weights"] = flex.double( len(reflections), self._delpsi_constant ) return reflections
[docs]class ExternalDelPsiWeightingStrategy(StatisticalWeightingStrategy): """Defines a single method that provides a ReflectionManager with a strategy for calculating weights for stills refinement. This version uses statistical weights for X and Y and assume that the Delta Psi part is already provided in the reflection table"""
[docs] def calculate_weights(self, reflections): """Statistical weights for X, Y. Weights for DeltaPsi must be already provided in the reflection table""" # call parent class method to set X and Y weights reflections = super().calculate_weights(reflections) if "delpsical.weights" not in reflections: raise DialsRefineConfigError( 'The key "delpsical.weights" is expected within the input reflections' ) return reflections
[docs]class ConstantWeightingStrategy:
[docs] def __init__(self, wx, wy, wz, stills=False): self._wx = wx self._wy = wy self._wz = wz self._stills = stills
[docs] def calculate_weights(self, reflections): """Set weights to constant terms. If stills, the z weights are the 'delpsical.weights' attribute of the reflection table. Otherwise, use the usual 'xyzobs.mm.weights'""" wx = flex.double(len(reflections), self._wx) wy = flex.double(len(reflections), self._wy) wz = flex.double(len(reflections), self._wz) if self._stills: null = flex.double(len(reflections), 0) reflections["xyzobs.mm.weights"] = flex.vec3_double(wx, wy, null) reflections["delpsical.weights"] = wz else: reflections["xyzobs.mm.weights"] = flex.vec3_double(wx, wy, wz) return reflections