Module meteor.diffmaps

library for computing difference density maps

Functions

def compute_difference_map(derivative: Map, native: Map, *, check_isomorphous: bool = True) ‑> Map
Expand source code
def compute_difference_map(derivative: Map, native: Map, *, check_isomorphous: bool = True) -> Map:
    """
    Computes amplitude and phase differences between native and derivative structure factor sets.

    It converts the amplitude and phase pairs from both the native and derivative structure factor
    sets into complex numbers, computes the difference, and then converts the result back
    into amplitudes and phases.

    If uncertainty columns are provided for both native and derivative data, it also propagates the
    uncertainty of the difference in amplitudes.

    Parameters
    ----------
    derivative: Map
        the derivative amplitudes, phases, uncertainties

    native: Map
        the native amplitudes, phases, uncertainties

    check_isomorphous: bool
        perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

    Returns
    -------
    diffmap: Map
        map corresponding to the complex difference (derivative - native)
    """
    assert_is_map(derivative, require_uncertainties=False)
    assert_is_map(native, require_uncertainties=False)
    if check_isomorphous:
        assert_isomorphous(derivative=derivative, native=native)

    derivative, native = filter_common_indices(derivative, native)

    delta_complex = derivative.to_structurefactor() - native.to_structurefactor()
    delta = Map.from_structurefactor(delta_complex)

    delta.cell = native.cell
    delta.spacegroup = native.spacegroup

    if derivative.has_uncertainties and native.has_uncertainties:
        prop_uncertainties = np.sqrt(derivative.uncertainties**2 + native.uncertainties**2)
        delta.set_uncertainties(prop_uncertainties)

    return delta

Computes amplitude and phase differences between native and derivative structure factor sets.

It converts the amplitude and phase pairs from both the native and derivative structure factor sets into complex numbers, computes the difference, and then converts the result back into amplitudes and phases.

If uncertainty columns are provided for both native and derivative data, it also propagates the uncertainty of the difference in amplitudes.

Parameters

derivative : Map
the derivative amplitudes, phases, uncertainties
native : Map
the native amplitudes, phases, uncertainties
check_isomorphous : bool
perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

Returns

diffmap : Map
map corresponding to the complex difference (derivative - native)
def compute_kweighted_difference_map(derivative: Map, native: Map, *, k_parameter: float, check_isomorphous: bool = True) ‑> Map
Expand source code
def compute_kweighted_difference_map(
    derivative: Map, native: Map, *, k_parameter: float, check_isomorphous: bool = True
) -> Map:
    """
    Compute k-weighted derivative - native structure factor map.

    This function first computes the standard difference map using `compute_difference_map`.
    Then, it applies k-weighting to the amplitude differences based on the provided `k_parameter`.

    Assumes amplitudes have already been scaled prior to invoking this function.

    Parameters
    ----------
    derivative: Map
        the derivative amplitudes, phases, uncertainties

    native: Map
        the native amplitudes, phases, uncertainties

    check_isomorphous: bool
        perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

    Returns
    -------
    diffmap: Map
        the k-weighted difference map
    """
    # require uncertainties at the beginning
    assert_is_map(derivative, require_uncertainties=True)
    assert_is_map(native, require_uncertainties=True)
    if check_isomorphous:
        assert_isomorphous(derivative=derivative, native=native)

    difference_map = compute_difference_map(derivative, native, check_isomorphous=check_isomorphous)
    weights = compute_kweights(difference_map, k_parameter=k_parameter)

    difference_map.amplitudes *= weights
    difference_map.uncertainties *= weights

    return difference_map

Compute k-weighted derivative - native structure factor map.

This function first computes the standard difference map using compute_difference_map(). Then, it applies k-weighting to the amplitude differences based on the provided k_parameter.

Assumes amplitudes have already been scaled prior to invoking this function.

Parameters

derivative : Map
the derivative amplitudes, phases, uncertainties
native : Map
the native amplitudes, phases, uncertainties
check_isomorphous : bool
perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

Returns

diffmap : Map
the k-weighted difference map
def compute_kweights(difference_map: Map, *, k_parameter: float) ‑> reciprocalspaceship.dataseries.DataSeries
Expand source code
def compute_kweights(difference_map: Map, *, k_parameter: float) -> rs.DataSeries:
    """
    Compute weights for each structure factor based on DeltaF and its uncertainty.

    Parameters
    ----------
    difference_map: Map
        A map of structure factor differences (DeltaF).

    k_parameter: float
        A scaling factor applied to the squared `df` values in the weight calculation.

    Returns
    -------
    weights: rs.DataSeries
        A series of computed weights, where higher uncertainties and larger differences lead to
        lower weights.
    """
    assert_is_map(difference_map, require_uncertainties=True)

    inverse_weights = (
        1
        + (difference_map.uncertainties**2 / (difference_map.uncertainties**2).mean())
        + k_parameter * (difference_map.amplitudes**2 / (difference_map.amplitudes**2).mean())
    )
    return 1.0 / inverse_weights

Compute weights for each structure factor based on DeltaF and its uncertainty.

Parameters

difference_map : Map
A map of structure factor differences (DeltaF).
k_parameter : float
A scaling factor applied to the squared df values in the weight calculation.

Returns

weights : rs.DataSeries
A series of computed weights, where higher uncertainties and larger differences lead to lower weights.
def max_negentropy_kweighted_difference_map(derivative: Map,
native: Map,
*,
k_parameter_values_to_scan: np.ndarray | Sequence[float] = array([0. , 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1 , 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2 , 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3 , 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4 , 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5 , 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.7 , 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8 , 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9 , 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1. ]),
check_isomorphous: bool = True) ‑> reciprocalspaceship.dataset.DataSet
Expand source code
def max_negentropy_kweighted_difference_map(
    derivative: Map,
    native: Map,
    *,
    k_parameter_values_to_scan: np.ndarray | Sequence[float] = DEFAULT_KPARAMS_TO_SCAN,
    check_isomorphous: bool = True,
) -> rs.DataSet:
    """
    Compute k-weighted differences between native and derivative amplitudes and phases.

    Determines an "optimal" k_parameter, between 0.0 and 1.0, that maximizes the resulting
    difference map negentropy. Assumes that scaling has already been applied to the amplitudes
    before calling this function.

    Parameters
    ----------
    derivative: Map
        the derivative amplitudes, phases, uncertainties

    native: Map
        the native amplitudes, phases, uncertainties

    k_parameter_values_to_scan : np.ndarray | Sequence[float]
        The values to scan to optimize the k-weighting parameter, by default is 0.00, 0.01 ... 1.00

    check_isomorphous: bool
        perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

    Returns
    -------
    kweighted_dataset: rs.DataSet
        dataset with added columns

    opt_k_parameter: float
        optimized k-weighting parameter
    """
    assert_is_map(derivative, require_uncertainties=True)
    assert_is_map(native, require_uncertainties=True)
    if check_isomorphous:
        assert_isomorphous(derivative=derivative, native=native)

    def negentropy_objective(k_parameter: float) -> float:
        kweighted_map = compute_kweighted_difference_map(
            derivative,
            native,
            k_parameter=k_parameter,
            check_isomorphous=check_isomorphous,
        )
        return map_negentropy(kweighted_map)

    maximizer = ScalarMaximizer(objective=negentropy_objective)
    maximizer.optimize_over_explicit_values(arguments_to_scan=k_parameter_values_to_scan)
    opt_k_parameter = float(maximizer.argument_optimum)

    kweighted_dataset = compute_kweighted_difference_map(
        derivative,
        native,
        k_parameter=opt_k_parameter,
        check_isomorphous=check_isomorphous,
    )

    return kweighted_dataset, opt_k_parameter

Compute k-weighted differences between native and derivative amplitudes and phases.

Determines an "optimal" k_parameter, between 0.0 and 1.0, that maximizes the resulting difference map negentropy. Assumes that scaling has already been applied to the amplitudes before calling this function.

Parameters

derivative : Map
the derivative amplitudes, phases, uncertainties
native : Map
the native amplitudes, phases, uncertainties
k_parameter_values_to_scan : np.ndarray | Sequence[float]
The values to scan to optimize the k-weighting parameter, by default is 0.00, 0.01 … 1.00
check_isomorphous : bool
perform a check to ensure the two datasets are isomorphous; recommended. Default: True.

Returns

kweighted_dataset : rs.DataSet
dataset with added columns
opt_k_parameter : float
optimized k-weighting parameter