Module meteor.tv
total variation denoising of maps
Functions
def tv_denoise_difference_map(difference_map: Map,
*,
full_output: bool = False,
weights_to_scan: Sequence[float] | np.ndarray | None = None) ‑> Map | tuple[Map, TvScanMetadata]-
Expand source code
def tv_denoise_difference_map( difference_map: Map, *, full_output: bool = False, weights_to_scan: Sequence[float] | np.ndarray | None = None, ) -> Map | tuple[Map, TvScanMetadata]: """Single-pass TV denoising of a difference map. Automatically selects the optimal level of regularization (the TV weight, aka lambda) by maximizing the negentropy of the denoised map. Two modes can be used to dictate which candidate values of weights are assessed: 1. By default (`weights_to_scan=None`), the golden-section search algorithm selects a weights value according to the bounds and convergence criteria set in meteor.settings. 2. Alternatively, an explicit list of weights values to assess can be provided using `weights_to_scan`. Parameters ---------- difference_map : Map The input dataset containing the difference map coefficients (amplitude and phase) that will be used to compute the difference map. full_output : bool, optional If `True`, the function returns both the denoised map coefficients and a `TvScanMetadata` object containing the optimal weight and the associated negentropy. If `False`, only the denoised map coefficients are returned. Default is `False`. weights_to_scan : Sequence[float] | None, optional A sequence of weight values to explicitly scan for determining the optimal value. If `None`, the function uses the golden-section search method to determine the optimal weight. Default is `None`. Returns ------- Map | tuple[Map, TvScanMetadata] If `full_output` is `False`, returns a `Map`, the denoised map coefficients. If `full_output` is `True`, returns a tuple containing: - `Map`: The denoised map coefficients. - `TvScanMetadata`: An object w/ the optimal weight and the corresponding negentropy. Raises ------ AssertionError If the golden-section search fails to find an optimal weight. Notes ----- - The function is designed to maximize the negentropy of the denoised map, which is a measure of the map's "randomness." Higher negentropy generally corresponds to a more informative and less noisy map. - The golden-section search is a robust method for optimizing unimodal functions, particularly suited for scenarios where an explicit list of candidate values is not provided. Example ------- >>> coefficients = Map.read_mtz("./path/to/difference_map.mtz", ...) # load dataset >>> denoised_map, result = tv_denoise_difference_map(coefficients, full_output=True) >>> print(f"Optimal: {result.optimal_tv_weight}, Negentropy: {result.optimal_negentropy}") """ realspace_map_array = difference_map.to_3d_numpy_map(map_sampling=MAP_SAMPLING) def negentropy_objective(tv_weight: float) -> float: denoised_map = _tv_denoise_array(map_as_array=realspace_map_array, weight=tv_weight) return negentropy(denoised_map) maximizer = ScalarMaximizer(objective=negentropy_objective) if weights_to_scan is not None: maximizer.optimize_over_explicit_values(arguments_to_scan=weights_to_scan) else: maximizer.optimize_with_golden_algorithm(bracket=BRACKET_FOR_GOLDEN_OPTIMIZATION) if maximizer.argument_optimum > TV_MAX_WEIGHT_EXPECTED: log.warning( "TV regularization weight much larger than expected, something probably went wrong", weight=f"{maximizer.argument_optimum:.2f}", limit=TV_MAX_WEIGHT_EXPECTED, ) # denoise using the optimized parameters and convert to an rs.DataSet final_realspace_map_as_array = _tv_denoise_array( map_as_array=realspace_map_array, weight=maximizer.argument_optimum, ) final_map = Map.from_3d_numpy_map( final_realspace_map_as_array, spacegroup=difference_map.spacegroup, cell=difference_map.cell, high_resolution_limit=difference_map.resolution_limits[1], ) # propogate uncertainties if difference_map.has_uncertainties: final_map.set_uncertainties(difference_map.uncertainties) if full_output: initial_negentropy = negentropy(realspace_map_array) tv_result = TvScanMetadata( initial_negentropy=float(initial_negentropy), optimal_parameter_value=float(maximizer.argument_optimum), optimal_negentropy=float(maximizer.objective_maximum), map_sampling=MAP_SAMPLING, parameter_scan_results=maximizer.parameter_scan_results, ) return final_map, tv_result return final_map
Single-pass TV denoising of a difference map.
Automatically selects the optimal level of regularization (the TV weight, aka lambda) by maximizing the negentropy of the denoised map. Two modes can be used to dictate which candidate values of weights are assessed:
- By default (
weights_to_scan=None
), the golden-section search algorithm selects a weights value according to the bounds and convergence criteria set in meteor.settings. - Alternatively, an explicit list of weights values to assess can be provided using
weights_to_scan
.
Parameters
difference_map
:Map
- The input dataset containing the difference map coefficients (amplitude and phase) that will be used to compute the difference map.
full_output
:bool
, optional- If
True
, the function returns both the denoised map coefficients and aTvScanMetadata
object containing the optimal weight and the associated negentropy. IfFalse
, only the denoised map coefficients are returned. Default isFalse
. weights_to_scan
:Sequence[float] | None
, optional- A sequence of weight values to explicitly scan for determining the optimal value. If
None
, the function uses the golden-section search method to determine the optimal weight. Default isNone
.
Returns
Map | tuple[Map, TvScanMetadata]
- If
full_output
isFalse
, returns aMap
, the denoised map coefficients. Iffull_output
isTrue
, returns a tuple containing: -Map
: The denoised map coefficients. -TvScanMetadata
: An object w/ the optimal weight and the corresponding negentropy.
Raises
AssertionError
- If the golden-section search fails to find an optimal weight.
Notes
- The function is designed to maximize the negentropy of the denoised map, which is a measure of the map's "randomness." Higher negentropy generally corresponds to a more informative and less noisy map.
- The golden-section search is a robust method for optimizing unimodal functions, particularly suited for scenarios where an explicit list of candidate values is not provided.
Example
>>> coefficients = Map.read_mtz("./path/to/difference_map.mtz", ...) # load dataset >>> denoised_map, result = tv_denoise_difference_map(coefficients, full_output=True) >>> print(f"Optimal: {result.optimal_tv_weight}, Negentropy: {result.optimal_negentropy}")
- By default (