From 3a5f58355c37af06d2a43923cddfe540e68bf9f5 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Mon, 15 May 2023 12:00:21 -0700 Subject: [PATCH 001/362] starting to add parameter class --- py4DSTEM/process/phase/parameter_optimize.py | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 py4DSTEM/process/phase/parameter_optimize.py diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py new file mode 100644 index 000000000..c3a377fb4 --- /dev/null +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -0,0 +1,75 @@ +from tqdm import tqdm +from skopt import gp_minimize +from skopt.space import Real, Integer, Categorical +from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective +from skopt.utils import use_named_args + +from functools import partialmethod +from typing import Union + +from py4DSTEM.process.phase import PtychographicReconstruction + +class PtychographyOptimizer: + """ + doot doot + """ + + def __init__( + self, + reconstruction_type: type[PtychographicReconstruction], + ): + """ + Parameter optimization for ptychographic reconstruction based on Bayesian Optimization + with Gaussian Process. + """ + pass + + def optimize(self,): + pass + + def visualize(self,): + pass + +class OptimizationParameter: + """ + Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer + """ + + def __init__( + self, + name:str, + lower_bound:Union[float,int,bool], + upper_bound:Union[float,int,bool], + initial_value:Union[float,int,bool], + scaling:str='uniform', + space:str="real", + categories:list=[], + ): + + # Check input + space = space.lower() + assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + + scaling = scaling.lower() + assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + + # Get the right scikit-optimize class + space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + param = space_map[space] + + # If a boolean property, the categories are True/False + if space == 'bool': + categories = [True, False] + + # store necessary information + self.name = name + self.initial_value = initial_value + + if param is Categorical: + assert categories is not None, "Empty list of categories!" + self._skopt_param = param(name=name, categories=categories) + else: + self._skopt_param = param(name=name, low=lower_bound, high=upper_bound, prior=scaling,) + + + From c1572df7a4608ed497f4ea1206bf86ac4ad1c4ef Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 14:59:04 -0700 Subject: [PATCH 002/362] bayesian optimization for hyperparameter tuning in ptychography --- py4DSTEM/process/phase/parameter_optimize.py | 285 +++++++++++++++---- 1 file changed, 224 insertions(+), 61 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c3a377fb4..c41c611ec 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -3,73 +3,236 @@ from skopt.space import Real, Integer, Categorical from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective from skopt.utils import use_named_args +import matplotlib.pyplot as plt -from functools import partialmethod +from functools import partial from typing import Union -from py4DSTEM.process.phase import PtychographicReconstruction +from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction class PtychographyOptimizer: - """ - doot doot - """ - - def __init__( - self, - reconstruction_type: type[PtychographicReconstruction], - ): - """ - Parameter optimization for ptychographic reconstruction based on Bayesian Optimization - with Gaussian Process. - """ - pass - - def optimize(self,): - pass - - def visualize(self,): - pass + """ + doot doot + """ + + def __init__( + self, + reconstruction_type: type[PhaseReconstruction], + init_args:dict, + preprocess_args:dict, + reconstruction_args:dict, + ): + """ + Parameter optimization for ptychographic reconstruction based on Bayesian Optimization + with Gaussian Process. + """ + + # loop over each argument dictionary and split into static and optimization variables + self._init_static_args, self._init_optimize_args = self._split_static_and_optimization_vars(init_args) + self._preprocess_static_args, self._preprocess_optimize_args = self._split_static_and_optimization_vars(preprocess_args) + self._reconstruction_static_args, self._reconstruction_optimize_args = self._split_static_and_optimization_vars(reconstruction_args) + + # Save list of skopt parameter objects and inital guess + self._parameter_list = [] + self._x0 = [] + for k,v in (self._init_optimize_args|self._preprocess_optimize_args|self._reconstruction_optimize_args).items(): + self._parameter_list.append(v._get(k)) + self._x0.append(v._initial_value) + + self._init_args = init_args + self._preprocess_args = preprocess_args + self._reconstruction_args = reconstruction_args + + self._reconstruction_type = reconstruction_type + + self._set_optimizer_defaults() + + def optimize( + self, + n_calls:int, + n_initial_points:int, + ): + + self._optimization_function = self._get_optimization_function( + self._reconstruction_type, + self._parameter_list, + n_calls, + self._init_static_args, + self._preprocess_static_args, + self._reconstruction_static_args, + self._init_optimize_args, + self._preprocess_optimize_args, + self._reconstruction_optimize_args + ) + + self._skopt_result = gp_minimize( + self._optimization_function, + self._parameter_list, + n_calls = n_calls, + n_initial_points=n_initial_points, + x0 = self._x0 + ) + return self + + def visualize(self,): + if len(self._parameter_list) == 1: + plot_gaussian_process(self._skopt_result) + plt.show() + + plot_convergence(self._skopt_result) + plt.show() + plot_objective(self._skopt_result) + plt.show() + plot_evaluations(self._skopt_result) + plt.show() + return self + + def get_optimized_arguments(self): + init_opt = self._replace_optimized_parameters(self._init_args, self._parameter_list) + prep_opt = self._replace_optimized_parameters(self._preprocess_args, self._parameter_list) + reco_opt = self._replace_optimized_parameters(self._reconstruction_args, self._parameter_list) + + return init_opt, prep_opt, reco_opt + + def _replace_optimized_parameters(self, arg_dict, parameters): + opt_args = {} + for k,v in arg_dict.items(): + # Check for optimization parameters + if isinstance(v,OptimizationParameter): + # Find the right parameter in the list + # There is probably a better way to do this inverse mapping! + for i,p in enumerate(parameters): + if p.name == k: + opt_args[k] = self._skopt_result.x[i] + else: + opt_args[k] = v + return opt_args + + + def _split_static_and_optimization_vars(self,argdict): + static_args = {} + optimization_args = {} + for k,v in argdict.items(): + if isinstance(v,OptimizationParameter): + # unwrap the OptimizationParameter object into a skopt object + optimization_args[k] = v #._get(k) + else: + static_args[k] = v + return static_args, optimization_args + + + def _get_optimization_function( + self, + cls:type[PhaseReconstruction], + parameter_list:list, + n_iterations:int, + init_static_args:dict, + preprocess_static_args:dict, + reconstruct_static_args:dict, + init_optimization_param_names:dict, + preprocess_optimization_param_names:dict, + reconstruct_optimization_param_names:dict): + """ + Wrap the ptychography pipeline into a single function that encapsulates all of the + non-optimization arguments and accepts a concatenated set of keyword arguments. The + wrapper function returns the final error value from the ptychography run. + + parameter_list is a list of skopt Dimension objects + + Both static and optimization args are passed in dictionaries. The values of the + static dictionary are the fixed parameters, and only the keys of the optimization + dictionary are used. + """ + + # Construct partial methods to encapsulate the static parameters + obj = partial(cls,**init_static_args) + prep = partial(cls.preprocess, **preprocess_static_args) + recon = partial(cls.reconstruct, **reconstruct_static_args) + + init_params = list(init_optimization_param_names.keys()) + prep_params = list(preprocess_optimization_param_names.keys()) + reco_params = list(reconstruct_optimization_param_names.keys()) + + # Make a progress bar + pbar = tqdm(total=n_iterations,desc="Optimizing Parameters") + + # Target function for Gaussian process optimization that takes a single + # dict of named parameters and returns the ptycho error metric + @use_named_args(parameter_list) + def f(**kwargs): + init_args = {k:kwargs[k] for k in init_params} + prep_args = {k:kwargs[k] for k in prep_params} + reco_args = {k:kwargs[k] for k in reco_params} + + ptycho = obj(**init_args) + prep(ptycho,**prep_args) + recon(ptycho,**reco_args) + + pbar.update(1) + + return ptycho.error + + return f + + def _set_optimizer_defaults(self): + """ + Set all of the verbose and plotting to False + """ + self._init_static_args['verbose'] = False + + self._preprocess_static_args['plot_center_of_mass'] = False + self._preprocess_static_args['plot_rotation'] = False + self._preprocess_static_args['plot_probe_overlaps'] = False + + self._reconstruction_static_args['progress_bar'] = False + self._reconstruction_static_args['store_iterations'] = False -class OptimizationParameter: - """ - Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer - """ - - def __init__( - self, - name:str, - lower_bound:Union[float,int,bool], - upper_bound:Union[float,int,bool], - initial_value:Union[float,int,bool], - scaling:str='uniform', - space:str="real", - categories:list=[], - ): - - # Check input - space = space.lower() - assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" - - scaling = scaling.lower() - assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" - - # Get the right scikit-optimize class - space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} - param = space_map[space] - - # If a boolean property, the categories are True/False - if space == 'bool': - categories = [True, False] - - # store necessary information - self.name = name - self.initial_value = initial_value - - if param is Categorical: - assert categories is not None, "Empty list of categories!" - self._skopt_param = param(name=name, categories=categories) - else: - self._skopt_param = param(name=name, low=lower_bound, high=upper_bound, prior=scaling,) +class OptimizationParameter: + """ + Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer + """ + + def __init__( + self, + lower_bound:Union[float,int,bool], + upper_bound:Union[float,int,bool], + initial_value:Union[float,int,bool], + scaling:str='uniform', + space:str="real", + categories:list=[], + ): + + # Check input + space = space.lower() + assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + + scaling = scaling.lower() + assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + + # Get the right scikit-optimize class + space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + param = space_map[space] + + # If a boolean property, the categories are True/False + if space == 'bool': + categories = [True, False] + + # store necessary information + self._initial_value = initial_value + self._categories = categories + self._lower_bound = lower_bound + self._upper_bound = upper_bound + self._scaling = scaling + self._param_type = param + + def _get(self,name): + self._name = name + if self._param_type is Categorical: + assert categories is not None, "Empty list of categories!" + self._skopt_param = self._param_type(name=self._name, categories=self._categories) + else: + self._skopt_param = self._param_type(name=self._name, low=self._lower_bound, high=self._upper_bound, prior=self._scaling,) + return self._skopt_param From 39cc862e8a2ad3a0c93dcc39a1987b173047bf6c Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 15:23:12 -0700 Subject: [PATCH 003/362] improvements to plotting and progress bar --- py4DSTEM/process/phase/parameter_optimize.py | 35 ++++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c41c611ec..1a5ad768b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -53,7 +53,7 @@ def optimize( n_initial_points:int, ): - self._optimization_function = self._get_optimization_function( + self._optimization_function, pbar = self._get_optimization_function( self._reconstruction_type, self._parameter_list, n_calls, @@ -72,19 +72,32 @@ def optimize( n_initial_points=n_initial_points, x0 = self._x0 ) + + # Finish the tqdm progressbar so subsequent things behave nicely + pbar.close() + return self - def visualize(self,): - if len(self._parameter_list) == 1: + def visualize( + self, + gp_model=True, + convergence=False, + objective=True, + evaluations=False, + ): + if len(self._parameter_list) == 1 and gp_model: plot_gaussian_process(self._skopt_result) plt.show() - plot_convergence(self._skopt_result) - plt.show() - plot_objective(self._skopt_result) - plt.show() - plot_evaluations(self._skopt_result) - plt.show() + if convergence: + plot_convergence(self._skopt_result) + plt.show() + if objective: + plot_objective(self._skopt_result) + plt.show() + if evaluations: + plot_evaluations(self._skopt_result) + plt.show() return self def get_optimized_arguments(self): @@ -154,7 +167,7 @@ def _get_optimization_function( reco_params = list(reconstruct_optimization_param_names.keys()) # Make a progress bar - pbar = tqdm(total=n_iterations,desc="Optimizing Parameters") + pbar = tqdm(total=n_iterations,desc="Optimizing parameters") # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @@ -172,7 +185,7 @@ def f(**kwargs): return ptycho.error - return f + return f, pbar def _set_optimizer_defaults(self): """ From 983db77e6c973c3d56aef240c51304e05c0b99dd Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 17:35:54 -0700 Subject: [PATCH 004/362] print optimization result --- py4DSTEM/process/phase/parameter_optimize.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 1a5ad768b..8d266e428 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -73,6 +73,10 @@ def optimize( x0 = self._x0 ) + print("Optimized parameters:") + for p,x in zip(self._parameter_list, self._skopt_result.x): + print(f"{p.name}: {x}") + # Finish the tqdm progressbar so subsequent things behave nicely pbar.close() From 62e03f80e6caeac8672def6f01c4b701414ab992 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 18:05:58 -0700 Subject: [PATCH 005/362] format --- py4DSTEM/process/phase/parameter_optimize.py | 181 +++++++++++-------- 1 file changed, 109 insertions(+), 72 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 8d266e428..627cb04c5 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -1,7 +1,12 @@ from tqdm import tqdm from skopt import gp_minimize from skopt.space import Real, Integer, Categorical -from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective +from skopt.plots import ( + plot_convergence, + plot_gaussian_process, + plot_evaluations, + plot_objective, +) from skopt.utils import use_named_args import matplotlib.pyplot as plt @@ -10,6 +15,7 @@ from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction + class PtychographyOptimizer: """ doot doot @@ -18,24 +24,37 @@ class PtychographyOptimizer: def __init__( self, reconstruction_type: type[PhaseReconstruction], - init_args:dict, - preprocess_args:dict, - reconstruction_args:dict, - ): + init_args: dict, + preprocess_args: dict, + reconstruction_args: dict, + ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization - with Gaussian Process. + with Gaussian Process. """ - + # loop over each argument dictionary and split into static and optimization variables - self._init_static_args, self._init_optimize_args = self._split_static_and_optimization_vars(init_args) - self._preprocess_static_args, self._preprocess_optimize_args = self._split_static_and_optimization_vars(preprocess_args) - self._reconstruction_static_args, self._reconstruction_optimize_args = self._split_static_and_optimization_vars(reconstruction_args) + ( + self._init_static_args, + self._init_optimize_args, + ) = self._split_static_and_optimization_vars(init_args) + ( + self._preprocess_static_args, + self._preprocess_optimize_args, + ) = self._split_static_and_optimization_vars(preprocess_args) + ( + self._reconstruction_static_args, + self._reconstruction_optimize_args, + ) = self._split_static_and_optimization_vars(reconstruction_args) # Save list of skopt parameter objects and inital guess self._parameter_list = [] self._x0 = [] - for k,v in (self._init_optimize_args|self._preprocess_optimize_args|self._reconstruction_optimize_args).items(): + for k, v in ( + self._init_optimize_args + | self._preprocess_optimize_args + | self._reconstruction_optimize_args + ).items(): self._parameter_list.append(v._get(k)) self._x0.append(v._initial_value) @@ -49,10 +68,9 @@ def __init__( def optimize( self, - n_calls:int, - n_initial_points:int, - ): - + n_calls: int, + n_initial_points: int, + ): self._optimization_function, pbar = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -62,19 +80,19 @@ def optimize( self._reconstruction_static_args, self._init_optimize_args, self._preprocess_optimize_args, - self._reconstruction_optimize_args - ) + self._reconstruction_optimize_args, + ) self._skopt_result = gp_minimize( self._optimization_function, self._parameter_list, - n_calls = n_calls, + n_calls=n_calls, n_initial_points=n_initial_points, - x0 = self._x0 + x0=self._x0, ) print("Optimized parameters:") - for p,x in zip(self._parameter_list, self._skopt_result.x): + for p, x in zip(self._parameter_list, self._skopt_result.x): print(f"{p.name}: {x}") # Finish the tqdm progressbar so subsequent things behave nicely @@ -105,50 +123,55 @@ def visualize( return self def get_optimized_arguments(self): - init_opt = self._replace_optimized_parameters(self._init_args, self._parameter_list) - prep_opt = self._replace_optimized_parameters(self._preprocess_args, self._parameter_list) - reco_opt = self._replace_optimized_parameters(self._reconstruction_args, self._parameter_list) + init_opt = self._replace_optimized_parameters( + self._init_args, self._parameter_list + ) + prep_opt = self._replace_optimized_parameters( + self._preprocess_args, self._parameter_list + ) + reco_opt = self._replace_optimized_parameters( + self._reconstruction_args, self._parameter_list + ) return init_opt, prep_opt, reco_opt def _replace_optimized_parameters(self, arg_dict, parameters): opt_args = {} - for k,v in arg_dict.items(): + for k, v in arg_dict.items(): # Check for optimization parameters - if isinstance(v,OptimizationParameter): + if isinstance(v, OptimizationParameter): # Find the right parameter in the list # There is probably a better way to do this inverse mapping! - for i,p in enumerate(parameters): + for i, p in enumerate(parameters): if p.name == k: opt_args[k] = self._skopt_result.x[i] else: opt_args[k] = v return opt_args - - def _split_static_and_optimization_vars(self,argdict): + def _split_static_and_optimization_vars(self, argdict): static_args = {} optimization_args = {} - for k,v in argdict.items(): - if isinstance(v,OptimizationParameter): + for k, v in argdict.items(): + if isinstance(v, OptimizationParameter): # unwrap the OptimizationParameter object into a skopt object - optimization_args[k] = v #._get(k) + optimization_args[k] = v # ._get(k) else: static_args[k] = v return static_args, optimization_args - def _get_optimization_function( self, - cls:type[PhaseReconstruction], - parameter_list:list, - n_iterations:int, - init_static_args:dict, - preprocess_static_args:dict, - reconstruct_static_args:dict, - init_optimization_param_names:dict, - preprocess_optimization_param_names:dict, - reconstruct_optimization_param_names:dict): + cls: type[PhaseReconstruction], + parameter_list: list, + n_iterations: int, + init_static_args: dict, + preprocess_static_args: dict, + reconstruct_static_args: dict, + init_optimization_param_names: dict, + preprocess_optimization_param_names: dict, + reconstruct_optimization_param_names: dict, + ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the non-optimization arguments and accepts a concatenated set of keyword arguments. The @@ -158,11 +181,11 @@ def _get_optimization_function( Both static and optimization args are passed in dictionaries. The values of the static dictionary are the fixed parameters, and only the keys of the optimization - dictionary are used. + dictionary are used. """ # Construct partial methods to encapsulate the static parameters - obj = partial(cls,**init_static_args) + obj = partial(cls, **init_static_args) prep = partial(cls.preprocess, **preprocess_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) @@ -171,38 +194,38 @@ def _get_optimization_function( reco_params = list(reconstruct_optimization_param_names.keys()) # Make a progress bar - pbar = tqdm(total=n_iterations,desc="Optimizing parameters") + pbar = tqdm(total=n_iterations, desc="Optimizing parameters") # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) def f(**kwargs): - init_args = {k:kwargs[k] for k in init_params} - prep_args = {k:kwargs[k] for k in prep_params} - reco_args = {k:kwargs[k] for k in reco_params} + init_args = {k: kwargs[k] for k in init_params} + prep_args = {k: kwargs[k] for k in prep_params} + reco_args = {k: kwargs[k] for k in reco_params} ptycho = obj(**init_args) - prep(ptycho,**prep_args) - recon(ptycho,**reco_args) + prep(ptycho, **prep_args) + recon(ptycho, **reco_args) pbar.update(1) return ptycho.error - + return f, pbar def _set_optimizer_defaults(self): """ Set all of the verbose and plotting to False """ - self._init_static_args['verbose'] = False + self._init_static_args["verbose"] = False - self._preprocess_static_args['plot_center_of_mass'] = False - self._preprocess_static_args['plot_rotation'] = False - self._preprocess_static_args['plot_probe_overlaps'] = False + self._preprocess_static_args["plot_center_of_mass"] = False + self._preprocess_static_args["plot_rotation"] = False + self._preprocess_static_args["plot_probe_overlaps"] = False - self._reconstruction_static_args['progress_bar'] = False - self._reconstruction_static_args['store_iterations'] = False + self._reconstruction_static_args["progress_bar"] = False + self._reconstruction_static_args["store_iterations"] = False class OptimizationParameter: @@ -212,27 +235,36 @@ class OptimizationParameter: def __init__( self, - lower_bound:Union[float,int,bool], - upper_bound:Union[float,int,bool], - initial_value:Union[float,int,bool], - scaling:str='uniform', - space:str="real", - categories:list=[], - ): - + lower_bound: Union[float, int, bool], + upper_bound: Union[float, int, bool], + initial_value: Union[float, int, bool], + scaling: str = "uniform", + space: str = "real", + categories: list = [], + ): # Check input space = space.lower() - assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + assert space in ( + "real", + "integer", + "bool", + "categorical", + ), f"Unknown Parameter type: {space}" scaling = scaling.lower() assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" # Get the right scikit-optimize class - space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + space_map = { + "real": Real, + "integer": Integer, + "bool": Categorical, + "categorical": Categorical, + } param = space_map[space] # If a boolean property, the categories are True/False - if space == 'bool': + if space == "bool": categories = [True, False] # store necessary information @@ -243,13 +275,18 @@ def __init__( self._scaling = scaling self._param_type = param - def _get(self,name): + def _get(self, name): self._name = name if self._param_type is Categorical: assert categories is not None, "Empty list of categories!" - self._skopt_param = self._param_type(name=self._name, categories=self._categories) + self._skopt_param = self._param_type( + name=self._name, categories=self._categories + ) else: - self._skopt_param = self._param_type(name=self._name, low=self._lower_bound, high=self._upper_bound, prior=self._scaling,) + self._skopt_param = self._param_type( + name=self._name, + low=self._lower_bound, + high=self._upper_bound, + prior=self._scaling, + ) return self._skopt_param - - From 3f1e05d54e12a1145db6bbbaa4d9c747eb341d12 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Thu, 18 May 2023 15:06:19 -0700 Subject: [PATCH 006/362] add affine transform to bayesian optimize --- py4DSTEM/process/phase/parameter_optimize.py | 73 +++++++++++++++----- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 627cb04c5..dbecdb22c 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -9,11 +9,13 @@ ) from skopt.utils import use_named_args import matplotlib.pyplot as plt +import numpy as np from functools import partial from typing import Union from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction +from py4DSTEM.process.phase.utils import AffineTransform class PtychographyOptimizer: @@ -25,6 +27,7 @@ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, + affine_args:dict, preprocess_args: dict, reconstruction_args: dict, ): @@ -38,6 +41,10 @@ def __init__( self._init_static_args, self._init_optimize_args, ) = self._split_static_and_optimization_vars(init_args) + ( + self._affine_static_args, + self._affine_optimize_args, + ) = self._split_static_and_optimization_vars(affine_args) ( self._preprocess_static_args, self._preprocess_optimize_args, @@ -52,6 +59,7 @@ def __init__( self._x0 = [] for k, v in ( self._init_optimize_args + | self._affine_optimize_args | self._preprocess_optimize_args | self._reconstruction_optimize_args ).items(): @@ -59,6 +67,7 @@ def __init__( self._x0.append(v._initial_value) self._init_args = init_args + self._affine_args = affine_args self._preprocess_args = preprocess_args self._reconstruction_args = reconstruction_args @@ -71,24 +80,34 @@ def optimize( n_calls: int, n_initial_points: int, ): - self._optimization_function, pbar = self._get_optimization_function( + self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, n_calls, self._init_static_args, + self._affine_static_args, self._preprocess_static_args, self._reconstruction_static_args, self._init_optimize_args, + self._affine_optimize_args, self._preprocess_optimize_args, self._reconstruction_optimize_args, ) + # Make a progress bar + pbar = tqdm(total=n_calls, desc="Optimizing parameters") + # We need to wrap the callback because if it returns a value + # the optimizer breaks its loop + def callback(*args,**kwargs): + pbar.update(1) + self._skopt_result = gp_minimize( self._optimization_function, self._parameter_list, n_calls=n_calls, n_initial_points=n_initial_points, x0=self._x0, + callback=callback, ) print("Optimized parameters:") @@ -107,10 +126,9 @@ def visualize( objective=True, evaluations=False, ): - if len(self._parameter_list) == 1 and gp_model: + if (len(self._parameter_list) == 1) and gp_model: plot_gaussian_process(self._skopt_result) plt.show() - if convergence: plot_convergence(self._skopt_result) plt.show() @@ -126,6 +144,13 @@ def get_optimized_arguments(self): init_opt = self._replace_optimized_parameters( self._init_args, self._parameter_list ) + affine_opt = self._replace_optimized_parameters( + self._affine_args, self._parameter_list + ) + affine_transform = partial(AffineTransform, **self._affine_static_args)(**affine_opt) + scan_positions = self._get_scan_positions(affine_transform, init_opt['datacube']) + init_opt['initial_scan_positions'] = scan_positions + prep_opt = self._replace_optimized_parameters( self._preprocess_args, self._parameter_list ) @@ -154,23 +179,32 @@ def _split_static_and_optimization_vars(self, argdict): optimization_args = {} for k, v in argdict.items(): if isinstance(v, OptimizationParameter): - # unwrap the OptimizationParameter object into a skopt object - optimization_args[k] = v # ._get(k) + optimization_args[k] = v else: static_args[k] = v return static_args, optimization_args + def _get_scan_positions(self, affine_transform, dataset): + R_pixel_size = dataset.calibration.get_R_pixel_size() + x,y = np.arange(dataset.R_Nx)*R_pixel_size, np.arange(dataset.R_Ny)*R_pixel_size + x, y = np.meshgrid(x, y, indexing="ij") + scan_positions = np.stack((x.ravel(),y.ravel()),axis=1) + scan_positions = scan_positions @ affine_transform.asarray() + return scan_positions + def _get_optimization_function( self, cls: type[PhaseReconstruction], parameter_list: list, n_iterations: int, init_static_args: dict, + affine_static_args:dict, preprocess_static_args: dict, reconstruct_static_args: dict, - init_optimization_param_names: dict, - preprocess_optimization_param_names: dict, - reconstruct_optimization_param_names: dict, + init_optimization_params: dict, + affine_optimization_params: dict, + preprocess_optimization_params: dict, + reconstruct_optimization_params: dict, ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the @@ -186,33 +220,38 @@ def _get_optimization_function( # Construct partial methods to encapsulate the static parameters obj = partial(cls, **init_static_args) + affine = partial(AffineTransform, **affine_static_args) prep = partial(cls.preprocess, **preprocess_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) - init_params = list(init_optimization_param_names.keys()) - prep_params = list(preprocess_optimization_param_names.keys()) - reco_params = list(reconstruct_optimization_param_names.keys()) - - # Make a progress bar - pbar = tqdm(total=n_iterations, desc="Optimizing parameters") + init_params = list(init_optimization_params.keys()) + afft_params = list(affine_optimization_params.keys()) + prep_params = list(preprocess_optimization_params.keys()) + reco_params = list(reconstruct_optimization_params.keys()) # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) def f(**kwargs): init_args = {k: kwargs[k] for k in init_params} + afft_args = {k: kwargs[k] for k in afft_params} prep_args = {k: kwargs[k] for k in prep_params} reco_args = {k: kwargs[k] for k in reco_params} + # Create affine transform object + tr = affine(**afft_args) + # Apply affine transform to pixel grid, using the + # calibrations lifted from the dataset + dataset = init_static_args['datacube'] + init_args['initial_scan_positions'] = self._get_scan_positions(tr, dataset) + ptycho = obj(**init_args) prep(ptycho, **prep_args) recon(ptycho, **reco_args) - pbar.update(1) - return ptycho.error - return f, pbar + return f def _set_optimizer_defaults(self): """ From 2aac54c1508260d8ea243b98feedba225d487249 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Thu, 18 May 2023 15:16:09 -0700 Subject: [PATCH 007/362] bugfix from linter --- py4DSTEM/process/phase/parameter_optimize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index dbecdb22c..dffa991ab 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -317,7 +317,7 @@ def __init__( def _get(self, name): self._name = name if self._param_type is Categorical: - assert categories is not None, "Empty list of categories!" + assert self._categories is not None, "Empty list of categories!" self._skopt_param = self._param_type( name=self._name, categories=self._categories ) From 57b363a0f84b637a97fa2df0cbc7e6bc4818d51c Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Fri, 19 May 2023 14:51:52 -0700 Subject: [PATCH 008/362] add documentation and format --- py4DSTEM/process/phase/parameter_optimize.py | 120 ++++++++++++++++--- 1 file changed, 106 insertions(+), 14 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index dffa991ab..987ffedef 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -20,20 +20,48 @@ class PtychographyOptimizer: """ - doot doot + Optimize ptychographic hyperparameters with Bayesian Optimization of a + Gaussian process. Any of the arguments to the ptychographic + init-preprocess-reconstruct pipeline can be optimized over (including + boolean or other flag options) """ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, - affine_args:dict, + affine_args: dict, preprocess_args: dict, reconstruction_args: dict, ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization with Gaussian Process. + + Usage + ----- + Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial + scan positions), preprocess, and reconstruct are required. For parameters not optimized + over, the value in the dictionary is used. To optimize a parameter, instead pass an + OptimizationParameter object inside the dictionary to specify the bounds, initial guess, + and type of parameter. Calling optimize will then run the optimization simultaneously + over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments + to return a set of dictionaries where the OptimizationParameter objects have been replaced + with the optimal values. These can then be modified for running a full reconstruction. + + Parameters + ---------- + reconstruction_type: class + Type of ptychographic reconstruction to perform + init_args: dict + Keyword arguments passed to the __init__ method of the reconstruction class + affine_args: dict + Keyword arguments passed to AffineTransform. The transform is applied to the initial + scan positions. + preprocess_args: dict + Keyword arguments passed to the preprocess method the reconstruction object + reconstruction_args: dict + Keyword arguments passed to the reconstruct method the the reconstruction object """ # loop over each argument dictionary and split into static and optimization variables @@ -79,7 +107,22 @@ def optimize( self, n_calls: int, n_initial_points: int, + **skopt_kwargs: dict, ): + """ + Run optimizer + + Parameters + ---------- + n_calls: int + Number of times to run ptychographic reconstruction + n_initial_points: int + Number of uniformly spaced trial points to test before + beginning Bayesian optimization (must be less than n_calls) + skopt_kwargs: dict + Additional arguments to be passed to skopt.gp_minimize + + """ self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -96,9 +139,10 @@ def optimize( # Make a progress bar pbar = tqdm(total=n_calls, desc="Optimizing parameters") + # We need to wrap the callback because if it returns a value # the optimizer breaks its loop - def callback(*args,**kwargs): + def callback(*args, **kwargs): pbar.update(1) self._skopt_result = gp_minimize( @@ -108,6 +152,7 @@ def callback(*args,**kwargs): n_initial_points=n_initial_points, x0=self._x0, callback=callback, + **skopt_kwargs, ) print("Optimized parameters:") @@ -126,6 +171,20 @@ def visualize( objective=True, evaluations=False, ): + """ + Visualize optimization results + + Parameters + ---------- + gp_model: bool + Display fitted Gaussian process model (only available for 1-dimensional problem) + convergence: bool + Display convergence history + objective: bool + Display GP objective function and partial dependence plots + evaluations: bool + Display histograms of sampled points + """ if (len(self._parameter_list) == 1) and gp_model: plot_gaussian_process(self._skopt_result) plt.show() @@ -141,15 +200,29 @@ def visualize( return self def get_optimized_arguments(self): + """ + Get argument dictionaries containing optimized hyperparameters + + Returns + ------- + init_opt, prep_opt, reco_opt: dicts + Dictionaries of arguments to __init__, preprocess, and reconstruct + where the OptimizationParameter items have been replaced with the optimal + values obtained from the optimizer + """ init_opt = self._replace_optimized_parameters( self._init_args, self._parameter_list ) affine_opt = self._replace_optimized_parameters( self._affine_args, self._parameter_list ) - affine_transform = partial(AffineTransform, **self._affine_static_args)(**affine_opt) - scan_positions = self._get_scan_positions(affine_transform, init_opt['datacube']) - init_opt['initial_scan_positions'] = scan_positions + affine_transform = partial(AffineTransform, **self._affine_static_args)( + **affine_opt + ) + scan_positions = self._get_scan_positions( + affine_transform, init_opt["datacube"] + ) + init_opt["initial_scan_positions"] = scan_positions prep_opt = self._replace_optimized_parameters( self._preprocess_args, self._parameter_list @@ -186,9 +259,12 @@ def _split_static_and_optimization_vars(self, argdict): def _get_scan_positions(self, affine_transform, dataset): R_pixel_size = dataset.calibration.get_R_pixel_size() - x,y = np.arange(dataset.R_Nx)*R_pixel_size, np.arange(dataset.R_Ny)*R_pixel_size + x, y = ( + np.arange(dataset.R_Nx) * R_pixel_size, + np.arange(dataset.R_Ny) * R_pixel_size, + ) x, y = np.meshgrid(x, y, indexing="ij") - scan_positions = np.stack((x.ravel(),y.ravel()),axis=1) + scan_positions = np.stack((x.ravel(), y.ravel()), axis=1) scan_positions = scan_positions @ affine_transform.asarray() return scan_positions @@ -198,7 +274,7 @@ def _get_optimization_function( parameter_list: list, n_iterations: int, init_static_args: dict, - affine_static_args:dict, + affine_static_args: dict, preprocess_static_args: dict, reconstruct_static_args: dict, init_optimization_params: dict, @@ -240,10 +316,10 @@ def f(**kwargs): # Create affine transform object tr = affine(**afft_args) - # Apply affine transform to pixel grid, using the + # Apply affine transform to pixel grid, using the # calibrations lifted from the dataset - dataset = init_static_args['datacube'] - init_args['initial_scan_positions'] = self._get_scan_positions(tr, dataset) + dataset = init_static_args["datacube"] + init_args["initial_scan_positions"] = self._get_scan_positions(tr, dataset) ptycho = obj(**init_args) prep(ptycho, **prep_args) @@ -274,13 +350,29 @@ class OptimizationParameter: def __init__( self, - lower_bound: Union[float, int, bool], - upper_bound: Union[float, int, bool], initial_value: Union[float, int, bool], + lower_bound: Union[float, int, bool] = None, + upper_bound: Union[float, int, bool] = None, scaling: str = "uniform", space: str = "real", categories: list = [], ): + """ + Wrapper for scikit-optimize Space objects used as inputs to PtychographyOptimizer + + Parameters + ---------- + initial_value: + Initial value, used for first evaluation in optimizer + lower_bound, upper_bound: + Bounds on real or integer variables (not needed for bool or categorical) + scaling: str + Prior knowledge on sensitivity of the variable. Can be 'uniform' or 'log-uniform' + space: str + Type of variable. Can be 'real', 'integer', 'bool', or 'categorical' + categories: list + List of options for Categorical parameter + """ # Check input space = space.lower() assert space in ( From 0cde08db1fb4e984821a2ddeba7982a55c852a93 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Fri, 19 May 2023 14:57:52 -0700 Subject: [PATCH 009/362] add isotropic expansion option to AffineTransform --- py4DSTEM/process/phase/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 12028408a..504adebd4 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -644,6 +644,8 @@ class AffineTransform: x-translation t1: float y-translation + dilation: float + Isotropic expansion (multiplies scale0 and scale1) """ def __init__( @@ -654,9 +656,10 @@ def __init__( angle: float = 0.0, t0: float = 0.0, t1: float = 0.0, + dilation: float = 1.0, ): - self.scale0 = scale0 - self.scale1 = scale1 + self.scale0 = scale0 * dilation + self.scale1 = scale1 * dilation self.shear1 = shear1 self.angle = angle self.t0 = t0 From 40e1a1c918a53db26ba5e2f4e971dad72b2e4c83 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Wed, 17 May 2023 11:32:12 -0400 Subject: [PATCH 010/362] fix calibration move --- py4DSTEM/preprocess/preprocess.py | 3 +++ py4DSTEM/process/phase/iterative_base_class.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 76a12f4b5..82794b07d 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -565,6 +565,7 @@ def resample_data_diffraction( datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom @@ -596,6 +597,8 @@ def resample_data_diffraction( resampling_factor = np.concatenate(((1, 1), resampling_factor)) datacube.data = zoom(datacube.data, resampling_factor, order=1) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor[2]) + else: raise ValueError( f"'method' needs to be one of 'bilinear' or 'fourier', not {method}." diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 249b685b4..c2a522dc1 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -193,8 +193,7 @@ def _preprocess_datacube_and_vacuum_probe( output_size=diffraction_intensities_shape, force_nonnegative=True, ) - datacube.calibration.set_Q_pixel_size(Q_pixel_size / resampling_factor_x) - + if probe_roi_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = probe_roi_shape From 946cc77fc726d22f81cfca955a09d6f028cec8b0 Mon Sep 17 00:00:00 2001 From: RPSankaran Date: Mon, 29 May 2023 16:40:52 -0700 Subject: [PATCH 011/362] fix version bug in py4DSTEM dev setup.py python <3.11 changed to <=3.11.3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b7ca8ad39..710f20a8a 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ author_email='ben.savitzky@gmail.com', license='GNU GPLv3', keywords="STEM 4DSTEM", - python_requires='>=3.9,<3.11', + python_requires='>=3.9,<=3.11.3', install_requires=[ 'numpy >= 1.19', 'scipy >= 1.5.2', From a980eb67c376f88ee81945216b9751273bb97771 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 1 Jun 2023 13:56:32 -0700 Subject: [PATCH 012/362] doc strings modification --- py4DSTEM/process/phase/parameter_optimize.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 987ffedef..ce17ec023 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -43,9 +43,11 @@ def __init__( Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial scan positions), preprocess, and reconstruct are required. For parameters not optimized over, the value in the dictionary is used. To optimize a parameter, instead pass an - OptimizationParameter object inside the dictionary to specify the bounds, initial guess, - and type of parameter. Calling optimize will then run the optimization simultaneously - over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments + OptimizationParameter object inside the dictionary to specify the initial guess, bounds, + and type of parameter, for example: + >>> 'param':OptimizationParameter(initial guess, lower bound, upper bound) + Calling optimize will then run the optimization simultaneously over all + optimization parameters. To obtain the optimized parameters, call get_optimized_arguments to return a set of dictionaries where the OptimizationParameter objects have been replaced with the optimal values. These can then be modified for running a full reconstruction. From b24e0d257f985531131baae4427db9151ee42ab6 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 3 Jun 2023 12:13:26 -0400 Subject: [PATCH 013/362] backtracking in DPC --- py4DSTEM/process/phase/iterative_dpc.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index b2d8ef891..248512a66 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -602,6 +602,7 @@ def reconstruct( max_iter: int = 64, step_size: float = None, stopping_criterion: float = 1e-6, + backtrack: bool = True, progress_bar: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, @@ -666,6 +667,8 @@ def reconstruct( self._step_size = step_size if step_size is not None else 0.5 self._padded_phase_object = self._padded_phase_object_initial.copy() + previous_iteration = self._padded_phase_object.copy() + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -688,10 +691,19 @@ def reconstruct( break # forward operator - com_dx, com_dy, self.error, self._step_size = self._forward( + com_dx, com_dy, new_error, self._step_size = self._forward( self._padded_phase_object, mask, mask_inv, self.error, self._step_size ) + # if the error went up after the previous step, go back to the step + # before the error rose and continue with the halved step size + if (new_error > self.error) and backtrack: + self._padded_phase_object = previous_iteration + print(f"Iteration {a0}, step reduced to {self._step_size}") + continue + self.error = new_error + previous_iteration = self._padded_phase_object.copy() + # adjoint operator phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) From ce7f180f78b5299da9b12365c5e5b742389a5446 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 3 Jun 2023 12:16:40 -0400 Subject: [PATCH 014/362] DPC backtrack docs --- py4DSTEM/process/phase/iterative_dpc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 248512a66..d03990dc0 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -624,6 +624,10 @@ def reconstruct( Reconstruction update step size stopping_criterion: float, optional step_size below which reconstruction exits + backtrack: bool, optional + If True, steps that increase the error metric are rejected + and iteration continues with a reduced step size from the + previous iteration progress_bar: bool, optional If True, reconstruction progress bar will be printed gaussian_filter_sigma: float, optional From e3aa53dd390e47156ecfccc86e85b1df61da758f Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sun, 4 Jun 2023 11:07:46 -0400 Subject: [PATCH 015/362] add calibration overrides to ptycho base class --- .../process/phase/iterative_base_class.py | 164 +++++++++++------- 1 file changed, 104 insertions(+), 60 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index c2a522dc1..cfc5e6cb0 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -220,6 +220,9 @@ def _extract_intensities_and_calibrations_from_datacube( self, datacube: DataCube, require_calibrations: bool = False, + force_scan_sampling: Optional[float] = None, + force_angular_sampling: Optional[float] = None, + force_reciprocal_sampling: Optional[float] = None, ): """ Method to extract intensities and calibrations from datacube. @@ -230,6 +233,12 @@ def _extract_intensities_and_calibrations_from_datacube( Input 4D diffraction pattern intensities require_calibrations: bool If False, warning is issued instead of raising an error + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 Assigns -------- @@ -275,80 +284,115 @@ def _extract_intensities_and_calibrations_from_datacube( reciprocal_space_units = calibration.get_Q_pixel_units() # Real-space - if real_space_units == "pixels": - if require_calibrations: - raise ValueError("Real-space calibrations must be given in 'A'") - - warnings.warn( - ( - "Iterative reconstruction will not be quantitative unless you specify " - "real-space calibrations in 'A'" - ), - UserWarning, - ) + if force_scan_sampling is not None: + self._scan_sampling = (force_scan_sampling, force_scan_sampling) + self._scan_units = "A" + else: + if real_space_units == "pixels": + if require_calibrations: + raise ValueError("Real-space calibrations must be given in 'A'") - self._scan_sampling = (1.0, 1.0) - self._scan_units = ("pixels",) * 2 + warnings.warn( + ( + "Iterative reconstruction will not be quantitative unless you specify " + "real-space calibrations in 'A'" + ), + UserWarning, + ) - elif real_space_units == "A": - self._scan_sampling = (calibration.get_R_pixel_size(),) * 2 - self._scan_units = ("A",) * 2 - elif real_space_units == "nm": - self._scan_sampling = (calibration.get_R_pixel_size() * 10,) * 2 - self._scan_units = ("A",) * 2 - else: - raise ValueError( - f"Real-space calibrations must be given in 'A', not {real_space_units}" - ) + self._scan_sampling = (1.0, 1.0) + self._scan_units = ("pixels",) * 2 - # Reciprocal-space - if reciprocal_space_units == "pixels": - if require_calibrations: + elif real_space_units == "A": + self._scan_sampling = (calibration.get_R_pixel_size(),) * 2 + self._scan_units = ("A",) * 2 + elif real_space_units == "nm": + self._scan_sampling = (calibration.get_R_pixel_size() * 10,) * 2 + self._scan_units = ("A",) * 2 + else: raise ValueError( - "Reciprocal-space calibrations must be given in in 'A^-1' or 'mrad'" + f"Real-space calibrations must be given in 'A', not {real_space_units}" ) - warnings.warn( - ( - "Iterative reconstruction will not be quantitative unless you specify " - "appropriate reciprocal-space calibrations" - ), - UserWarning, + # Reciprocal-space + if force_angular_sampling is not None or force_reciprocal_sampling is not None: + # there is no xor keyword in Python! + angular = force_angular_sampling is not None + reciprocal = force_reciprocal_sampling is not None + assert (angular and not reciprocal) or (not angular and reciprocal), ( + "Only one of angular or reciprocal calibration can be forced!" ) - self._angular_sampling = (1.0, 1.0) - self._angular_units = ("pixels",) * 2 - self._reciprocal_sampling = (1.0, 1.0) - self._reciprocal_units = ("pixels",) * 2 - - elif reciprocal_space_units == "A^-1": - reciprocal_size = calibration.get_Q_pixel_size() - self._reciprocal_sampling = (reciprocal_size,) * 2 - self._reciprocal_units = ("A^-1",) * 2 - - if self._energy is not None: - self._angular_sampling = ( - reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, - ) * 2 + # angular calibration specified + if angular: + self._angular_sampling = (force_angular_sampling,) * 2 self._angular_units = ("mrad",) * 2 - elif reciprocal_space_units == "mrad": - angular_size = calibration.get_Q_pixel_size() - self._angular_sampling = (angular_size,) * 2 - self._angular_units = ("mrad",) * 2 + if self._energy is not None: + self._reciprocal_sampling = ( + force_angular_sampling / electron_wavelength_angstrom(self._energy) / 1e3, + ) * 2 + self._reciprocal_units = ("A^-1",) * 2 - if self._energy is not None: - self._reciprocal_sampling = ( - angular_size / electron_wavelength_angstrom(self._energy) / 1e3, - ) * 2 + # reciprocal calibration specified + if reciprocal: + self._reciprocal_sampling = (force_reciprocal_sampling,) * 2 self._reciprocal_units = ("A^-1",) * 2 + + if self._energy is not None: + self._angular_sampling = ( + force_reciprocal_sampling * electron_wavelength_angstrom(self._energy) * 1e3, + ) * 2 + self._angular_units = ("mrad",) * 2 + else: - raise ValueError( - ( - "Reciprocal-space calibrations must be given in 'A^-1' or 'mrad', " - f"not {reciprocal_space_units}" + if reciprocal_space_units == "pixels": + if require_calibrations: + raise ValueError( + "Reciprocal-space calibrations must be given in in 'A^-1' or 'mrad'" + ) + + warnings.warn( + ( + "Iterative reconstruction will not be quantitative unless you specify " + "appropriate reciprocal-space calibrations" + ), + UserWarning, + ) + + self._angular_sampling = (1.0, 1.0) + self._angular_units = ("pixels",) * 2 + self._reciprocal_sampling = (1.0, 1.0) + self._reciprocal_units = ("pixels",) * 2 + + elif reciprocal_space_units == "A^-1": + reciprocal_size = calibration.get_Q_pixel_size() + self._reciprocal_sampling = (reciprocal_size,) * 2 + self._reciprocal_units = ("A^-1",) * 2 + + if self._energy is not None: + self._angular_sampling = ( + reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, + ) * 2 + self._angular_units = ("mrad",) * 2 + + elif reciprocal_space_units == "mrad": + angular_size = calibration.get_Q_pixel_size() + self._angular_sampling = (angular_size,) * 2 + self._angular_units = ("mrad",) * 2 + + if self._energy is not None: + self._reciprocal_sampling = ( + angular_size / electron_wavelength_angstrom(self._energy) / 1e3, + ) * 2 + self._reciprocal_units = ("A^-1",) * 2 + else: + raise ValueError( + ( + "Reciprocal-space calibrations must be given in 'A^-1' or 'mrad', " + f"not {reciprocal_space_units}" + ) ) - ) return intensities From db0b1c2c01af9fccb97f4741df83d685a84e5360 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 5 Jun 2023 11:31:39 -0700 Subject: [PATCH 016/362] no empty dictionaries required! --- py4DSTEM/process/phase/parameter_optimize.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ce17ec023..0d1245a62 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -30,9 +30,9 @@ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, - affine_args: dict, preprocess_args: dict, reconstruction_args: dict, + affine_args: dict = None, ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization @@ -43,10 +43,10 @@ def __init__( Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial scan positions), preprocess, and reconstruct are required. For parameters not optimized over, the value in the dictionary is used. To optimize a parameter, instead pass an - OptimizationParameter object inside the dictionary to specify the initial guess, bounds, - and type of parameter, for example: + OptimizationParameter object inside the dictionary to specify the initial guess, bounds, + and type of parameter, for example: >>> 'param':OptimizationParameter(initial guess, lower bound, upper bound) - Calling optimize will then run the optimization simultaneously over all + Calling optimize will then run the optimization simultaneously over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments to return a set of dictionaries where the OptimizationParameter objects have been replaced with the optimal values. These can then be modified for running a full reconstruction. @@ -57,14 +57,16 @@ def __init__( Type of ptychographic reconstruction to perform init_args: dict Keyword arguments passed to the __init__ method of the reconstruction class - affine_args: dict - Keyword arguments passed to AffineTransform. The transform is applied to the initial - scan positions. preprocess_args: dict Keyword arguments passed to the preprocess method the reconstruction object reconstruction_args: dict Keyword arguments passed to the reconstruct method the the reconstruction object + affine_args: dict + Keyword arguments passed to AffineTransform. The transform is applied to the initial + scan positions. """ + if affine_args is None: + affine_args = {} # loop over each argument dictionary and split into static and optimization variables ( From 809013ed559f509b79be3387abf2ced92cd79ad9 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 5 Jun 2023 15:04:52 -0400 Subject: [PATCH 017/362] bugfix and document previous commit --- py4DSTEM/preprocess/preprocess.py | 8 +++++++- .../process/phase/iterative_base_class.py | 6 +++--- .../iterative_singleslice_ptychography.py | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 82794b07d..03598b824 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -562,10 +562,16 @@ def resample_data_diffraction( ) resampling_factor = resampling_factor[0] + old_size = datacube.data.shape + datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + + if not resampling_factor: + resampling_factor = old_size[2] / output_size[0] + if datacube.calibration.get_Q_pixel_size() is not None: + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index cfc5e6cb0..eb3541dc4 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -220,9 +220,9 @@ def _extract_intensities_and_calibrations_from_datacube( self, datacube: DataCube, require_calibrations: bool = False, - force_scan_sampling: Optional[float] = None, - force_angular_sampling: Optional[float] = None, - force_reciprocal_sampling: Optional[float] = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, ): """ Method to extract intensities and calibrations from datacube. diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 3507f606b..67a843115 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -91,6 +91,7 @@ def __init__( energy: float, datacube: DataCube = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -156,6 +157,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -180,6 +182,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -229,6 +234,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -273,8 +284,16 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + ( self._com_measured_x, self._com_measured_y, From ed9f4ff208298c4de8fa9b6b23623bcbdd2d2608 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet <55254539+smribet@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:58:36 -0700 Subject: [PATCH 018/362] step size reorg --- py4DSTEM/process/phase/iterative_dpc.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index d03990dc0..27749758b 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -420,9 +420,6 @@ def _forward( xp.mean(self._com_x.ravel() ** 2 + self._com_y.ravel() ** 2) ) - if new_error > error: - step_size /= 2 - return obj_dx, obj_dy, new_error, step_size def _adjoint( @@ -670,9 +667,7 @@ def reconstruct( self.error = np.inf self._step_size = step_size if step_size is not None else 0.5 self._padded_phase_object = self._padded_phase_object_initial.copy() - - previous_iteration = self._padded_phase_object.copy() - + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -693,7 +688,9 @@ def reconstruct( ): if self._step_size < stopping_criterion: break - + + previous_iteration = self._padded_phase_object.copy() + # forward operator com_dx, com_dy, new_error, self._step_size = self._forward( self._padded_phase_object, mask, mask_inv, self.error, self._step_size @@ -703,10 +700,10 @@ def reconstruct( # before the error rose and continue with the halved step size if (new_error > self.error) and backtrack: self._padded_phase_object = previous_iteration + self._step_size /= 2 print(f"Iteration {a0}, step reduced to {self._step_size}") continue self.error = new_error - previous_iteration = self._padded_phase_object.copy() # adjoint operator phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) From 45a1c7162c9e40858a70c8868b68541a09dc305a Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 8 Jun 2023 10:04:25 -0700 Subject: [PATCH 019/362] anti gridding filter --- py4DSTEM/process/phase/iterative_dpc.py | 81 +++++++++++++++++++------ 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 27749758b..062bb8d5c 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -337,13 +337,13 @@ def preprocess( padded_object_shape = np.round( np.array(self._grid_scan_shape) * padding_factor ).astype("int") - self._padded_phase_object = xp.zeros(padded_object_shape, dtype=xp.float32) + self._padded_object_phase = xp.zeros(padded_object_shape, dtype=xp.float32) if self._object_phase is not None: - self._padded_phase_object[ + self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ] = xp.asarray(self._object_phase, dtype=xp.float32) - self._padded_phase_object_initial = self._padded_phase_object.copy() + self._padded_object_phase_initial = self._padded_object_phase.copy() # Fourier coordinates and operators kx = xp.fft.fftfreq(padded_object_shape[0], d=self._scan_sampling[0]) @@ -478,7 +478,7 @@ def _update( Returns -------- - updated_padded_phase_object: np.ndarray + updated_padded_object_phase: np.ndarray Updated padded phase object estimate """ @@ -547,6 +547,37 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): return xp.real(current_object) + def _object_anti_gridding_contraint(self, current_object): + """ + Zero outer pixels of object fft to remove gridding artifacts + + Parameters + -------- + current_object: np.ndarray + Current object estimate + + Returns + -------- + constrained_object: np.ndarray + Constrained object estimate + """ + xp = self._xp + + #find indices to zero accounting for object padding + width_x = self._grid_scan_shape[0] + width_y = self._grid_scan_shape[1] + ind_min_x = int(xp.floor(width_x / 2) - 1) + ind_max_x = int(xp.ceil(width_x / 2) + 1) + ind_min_y = int(xp.floor(width_y / 2) - 1) + ind_max_y = int(xp.ceil(width_y / 2) + 1) + + #zero pixels + object_fft = xp.fft.fft2(current_object) + object_fft[ind_min_x:-ind_max_x] = 0 + object_fft[:, ind_min_y:-ind_max_y] = 0 + + return xp.real(xp.fft.ifft2(object_fft)) + def _constraints( self, current_object, @@ -555,6 +586,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + anti_gridding, ): """ DPC constraints operator. @@ -573,6 +605,9 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + anti_gridding: bool + If true, zero outer pixels of object fft to remove + gridding artifacts Returns -------- @@ -591,6 +626,11 @@ def _constraints( q_highpass, ) + if anti_gridding: + current_object = self._object_anti_gridding_contraint( + current_object, + ) + return current_object def reconstruct( @@ -606,6 +646,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + anti_gridding: float = True, store_iterations: bool = False, ): """ @@ -637,6 +678,9 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + anti_gridding: bool + If true, zero outer pixels of object fft to remove + gridding artifacts store_iterations: bool, optional If True, all reconstruction iterations will be stored @@ -666,8 +710,8 @@ def reconstruct( if reset: self.error = np.inf self._step_size = step_size if step_size is not None else 0.5 - self._padded_phase_object = self._padded_phase_object_initial.copy() - + self._padded_object_phase = self._padded_object_phase_initial.copy() + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -675,7 +719,7 @@ def reconstruct( else: self._step_size = step_size - mask = xp.zeros(self._padded_phase_object.shape, dtype="bool") + mask = xp.zeros(self._padded_object_phase.shape, dtype="bool") mask[: self._grid_scan_shape[0], : self._grid_scan_shape[1]] = True mask_inv = xp.logical_not(mask) @@ -688,18 +732,18 @@ def reconstruct( ): if self._step_size < stopping_criterion: break - - previous_iteration = self._padded_phase_object.copy() - + + previous_iteration = self._padded_object_phase.copy() + # forward operator com_dx, com_dy, new_error, self._step_size = self._forward( - self._padded_phase_object, mask, mask_inv, self.error, self._step_size + self._padded_object_phase, mask, mask_inv, self.error, self._step_size ) # if the error went up after the previous step, go back to the step # before the error rose and continue with the halved step size if (new_error > self.error) and backtrack: - self._padded_phase_object = previous_iteration + self._padded_object_phase = previous_iteration self._step_size /= 2 print(f"Iteration {a0}, step reduced to {self._step_size}") continue @@ -709,13 +753,13 @@ def reconstruct( phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) # update - self._padded_phase_object = self._update( - self._padded_phase_object, phase_update, self._step_size + self._padded_object_phase = self._update( + self._padded_object_phase, phase_update, self._step_size ) # constraints - self._padded_phase_object = self._constraints( - self._padded_phase_object, + self._padded_object_phase = self._constraints( + self._padded_object_phase, gaussian_filter=a0 < gaussian_filter_iter and gaussian_filter_sigma is not None, gaussian_filter_sigma=gaussian_filter_sigma, @@ -723,12 +767,13 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + anti_gridding=anti_gridding, ) if store_iterations: self.object_phase_iterations.append( asnumpy( - self._padded_phase_object[ + self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ].copy() ) @@ -742,7 +787,7 @@ def reconstruct( ) # crop result - self._object_phase = self._padded_phase_object[ + self._object_phase = self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ] self.object_phase = asnumpy(self._object_phase) From 9045cca4ba9a5f444c568b43cee9ebd1b7e6ed68 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 8 Jun 2023 20:02:09 -0700 Subject: [PATCH 020/362] fix for anti gridding --- py4DSTEM/process/phase/iterative_dpc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 062bb8d5c..6711a21c6 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -563,18 +563,18 @@ def _object_anti_gridding_contraint(self, current_object): """ xp = self._xp - #find indices to zero accounting for object padding - width_x = self._grid_scan_shape[0] - width_y = self._grid_scan_shape[1] - ind_min_x = int(xp.floor(width_x / 2) - 1) - ind_max_x = int(xp.ceil(width_x / 2) + 1) - ind_min_y = int(xp.floor(width_y / 2) - 1) - ind_max_y = int(xp.ceil(width_y / 2) + 1) + #find indices to zero + width_x = current_object.shape[0] + width_y = current_object.shape[1] + ind_min_x = int(xp.floor(width_x / 2) - 2) + ind_max_x = int(xp.ceil(width_x / 2) + 2) + ind_min_y = int(xp.floor(width_y / 2) - 2) + ind_max_y = int(xp.ceil(width_y / 2) + 2) #zero pixels object_fft = xp.fft.fft2(current_object) - object_fft[ind_min_x:-ind_max_x] = 0 - object_fft[:, ind_min_y:-ind_max_y] = 0 + object_fft[ind_min_x:ind_max_x] = 0 + object_fft[:, ind_min_y:ind_max_y] = 0 return xp.real(xp.fft.ifft2(object_fft)) From af5218c4ee88a4d6125beb4337ebc4515c1c6a46 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 10 Jun 2023 15:46:18 -0700 Subject: [PATCH 021/362] butterworth order --- .../process/phase/iterative_base_class.py | 2 +- py4DSTEM/process/phase/iterative_dpc.py | 22 +++++++++++---- .../iterative_multislice_ptychography.py | 2 ++ .../iterative_overlap_magnetic_tomography.py | 28 +++++++++++++++---- .../phase/iterative_overlap_tomography.py | 22 +++++++++++---- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index c2acbee34..78a8b59f9 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -2181,6 +2181,6 @@ def positions(self): @property def _object_cropped(self): - """ cropped and rotated object """ + """cropped and rotated object""" return self._crop_rotate_object_fov(self._object) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 6711a21c6..f2c1bb20f 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -509,7 +509,9 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter used for low/high-pass filtering. @@ -521,6 +523,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- @@ -536,9 +540,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -563,7 +567,7 @@ def _object_anti_gridding_contraint(self, current_object): """ xp = self._xp - #find indices to zero + # find indices to zero width_x = current_object.shape[0] width_y = current_object.shape[1] ind_min_x = int(xp.floor(width_x / 2) - 2) @@ -571,7 +575,7 @@ def _object_anti_gridding_contraint(self, current_object): ind_min_y = int(xp.floor(width_y / 2) - 2) ind_max_y = int(xp.ceil(width_y / 2) + 2) - #zero pixels + # zero pixels object_fft = xp.fft.fft2(current_object) object_fft[ind_min_x:ind_max_x] = 0 object_fft[:, ind_min_y:ind_max_y] = 0 @@ -586,6 +590,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + butterworth_order, anti_gridding, ): """ @@ -605,6 +610,8 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter anti_gridding: bool If true, zero outer pixels of object fft to remove gridding artifacts @@ -624,6 +631,7 @@ def _constraints( current_object, q_lowpass, q_highpass, + butterworth_order, ) if anti_gridding: @@ -646,6 +654,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + butterworth_order: float = 2, anti_gridding: float = True, store_iterations: bool = False, ): @@ -678,6 +687,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter anti_gridding: bool If true, zero outer pixels of object fft to remove gridding artifacts @@ -767,6 +778,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, anti_gridding=anti_gridding, ) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a7fe53589..58f7152c4 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1331,6 +1331,8 @@ def _object_butterworth_constraint( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 9eda852a1..5b06a364d 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -327,9 +327,9 @@ def _euler_angle_rotate_volume( """ Rotate 3D volume using alpha, beta, gamma Euler angles according to convention: - - \-alpha tilt around first axis (z) - - \beta tilt around second axis (x) - - \alpha tilt around first axis (z) + - \\-alpha tilt around first axis (z) + - \\beta tilt around second axis (x) + - \\alpha tilt around first axis (z) Note: since we store array as zxy, the x- and y-axis rotations flip sign below. @@ -1591,7 +1591,9 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter @@ -1603,6 +1605,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- @@ -1618,9 +1622,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -1677,6 +1681,7 @@ def _constraints( q_lowpass_m, q_highpass_e, q_highpass_m, + butterworth_order, object_positivity, shrinkage_rad, object_mask, @@ -1732,6 +1737,8 @@ def _constraints( Cut-off frequency in A^-1 for high-pass filtering electrostatic object q_highpass_m: float Cut-off frequency in A^-1 for high-pass filtering magnetic object + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool If True, forces object to be positive shrinkage_rad: float @@ -1766,21 +1773,25 @@ def _constraints( current_object[0], q_lowpass_e, q_highpass_e, + butterworth_order, ) current_object[1] = self._object_butterworth_constraint( current_object[1], q_lowpass_m, q_highpass_m, + butterworth_order, ) current_object[2] = self._object_butterworth_constraint( current_object[2], q_lowpass_m, q_highpass_m, + butterworth_order, ) current_object[3] = self._object_butterworth_constraint( current_object[3], q_lowpass_m, q_highpass_m, + butterworth_order, ) if shrinkage_rad > 0.0 or object_mask is not None: @@ -1863,6 +1874,7 @@ def reconstruct( q_lowpass_m: float = None, q_highpass_e: float = None, q_highpass_m: float = None, + butterworth_order: float = 2, object_positivity: bool = True, shrinkage_rad: float = 0.0, fix_potential_baseline: bool = True, @@ -1942,6 +1954,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool, optional If True, forces object to be positive shrinkage_rad: float @@ -2408,6 +2422,7 @@ def reconstruct( q_lowpass_m=q_lowpass_m, q_highpass_e=q_highpass_e, q_highpass_m=q_highpass_m, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse @@ -2454,6 +2469,7 @@ def reconstruct( q_lowpass_m=q_lowpass_m, q_highpass_e=q_highpass_e, q_highpass_m=q_highpass_m, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 3337d02cc..c005081b2 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1492,13 +1492,15 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): """ gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter @@ -1510,7 +1512,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter - + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- constrained_object: np.ndarray @@ -1525,9 +1528,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -1557,6 +1560,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + butterworth_order, object_positivity, shrinkage_rad, object_mask, @@ -1605,6 +1609,8 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool If True, forces object to be positive shrinkage_rad: float @@ -1632,6 +1638,7 @@ def _constraints( current_object, q_lowpass, q_highpass, + butterworth_order, ) if shrinkage_rad > 0.0 or object_mask is not None: @@ -1711,6 +1718,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + butterworth_order: float = 2, object_positivity: bool = True, shrinkage_rad: float = 0.0, fix_potential_baseline: bool = True, @@ -1788,6 +1796,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool, optional If True, forces object to be positive shrinkage_rad: float @@ -2172,6 +2182,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse @@ -2213,6 +2224,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse From 3fc351c735bbddb59a437e86c541eecf237cc755 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 11 Jun 2023 11:29:28 -0700 Subject: [PATCH 022/362] fixing small butterworth order bug --- py4DSTEM/process/phase/iterative_dpc.py | 4 ++-- .../phase/iterative_overlap_magnetic_tomography.py | 10 +++++++--- py4DSTEM/process/phase/iterative_overlap_tomography.py | 10 +++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index f2c1bb20f..87741809d 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -540,9 +540,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 5b06a364d..60f3a1c3c 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1622,9 +1622,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -2439,7 +2439,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index c005081b2..6c773b269 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1528,9 +1528,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -2197,7 +2197,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, From 445cca1018b9e225cd230f8809e26a4f61ad31a9 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 11 Jun 2023 14:13:09 -0700 Subject: [PATCH 023/362] nesterov acceleration prefactors for reference. currently unused - see comment on PR #443 --- py4DSTEM/process/phase/utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index bb11db7d4..621223b60 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -2,6 +2,7 @@ import matplotlib.pyplot as plt import numpy as np +import functools try: import cupy as cp @@ -1284,3 +1285,16 @@ def project_vector_field_divergence(vector_field, spacings=(1, 1, 1), xp=np): p = preconditioned_poisson_solver(div_v, spacings[0], xp=xp) grad_p = compute_gradient(p, spacings, xp=xp) return vector_field - grad_p + +# Nesterov acceleration functions +# https://blogs.princeton.edu/imabandit/2013/04/01/acceleratedgradientdescent/ + +@functools.cache +def nesterov_lambda(one_indexed_iter_num): + if one_indexed_iter_num == 0: + return 0 + return (1+np.sqrt(1+4*nesterov_lambda(one_indexed_iter_num-1)**2))/2 + +def nesterov_gamma(zero_indexed_iter_num): + one_indexed_iter_num = zero_indexed_iter_num + 1 + return (1-nesterov_lambda(one_indexed_iter_num))/nesterov_lambda(one_indexed_iter_num+1) From 0e9c45786310b9bda85055985bdcb5703a4cb016 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Wed, 14 Jun 2023 08:42:58 -0700 Subject: [PATCH 024/362] step size default update --- py4DSTEM/process/phase/iterative_mixedstate_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 +- py4DSTEM/process/phase/iterative_simultaneous_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_singleslice_ptychography.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index d09b5a339..ff32f5b49 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1226,7 +1226,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 58f7152c4..c0e73e13b 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1623,7 +1623,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 60f3a1c3c..a41c83517 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1849,7 +1849,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6c773b269..36d32fba7 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1696,7 +1696,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index c655b82a1..c2a6f047f 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2398,7 +2398,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 8a83fa5ba..bccc54074 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1138,7 +1138,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, From 322bf371e8a13e18dbe7e3f5b529b6d7930b7110 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 14 Jun 2023 09:59:34 -0700 Subject: [PATCH 025/362] changing gaussian sigma normalization --- py4DSTEM/process/phase/iterative_dpc.py | 2 +- .../process/phase/iterative_overlap_magnetic_tomography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 +- .../process/phase/iterative_ptychographic_constraints.py | 6 ++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 87741809d..583128da5 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -504,7 +504,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): xp = self._xp gaussian_filter = self._gaussian_filter - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index a41c83517..aaede8dfc 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1586,7 +1586,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 36d32fba7..ac98738dc 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1493,7 +1493,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index d0a637204..2abad3d45 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -120,7 +120,7 @@ def _object_gaussian_constraint( """ xp = self._xp gaussian_filter = self._gaussian_filter - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] if pure_phase_object: phase = xp.angle(current_object) @@ -518,9 +518,7 @@ def _probe_residual_aberration_filtering_constraint( xp = self._xp gaussian_filter = self._gaussian_filter known_aberrations_array = self._known_aberrations_array - gaussian_filter_sigma /= xp.sqrt( - self._reciprocal_sampling[0] ** 2 + self._reciprocal_sampling[1] ** 2 - ) + gaussian_filter_sigma /= self._reciprocal_sampling[0] fourier_probe = self._return_fourier_probe(current_probe) if fix_amplitude: From f3c9c727ba5d536a5644b35fb97fc4d0ebd88ae7 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 14 Jun 2023 10:06:49 -0700 Subject: [PATCH 026/362] small device specification cleanup --- py4DSTEM/process/phase/iterative_parallax.py | 3 ++- py4DSTEM/process/phase/iterative_ptychographic_constraints.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 94f32ad12..5ab4c6cdd 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -79,6 +79,7 @@ def __init__( # Metadata self._energy = energy self._verbose = verbose + self._device = device self._object_padding_px = object_padding_px self._preprocessed = False @@ -725,7 +726,7 @@ def reconstruct( G_ref, G, upsample_factor=upsample_factor, - device="cpu" if xp is np else "gpu", + device=self._device, ) dx = ( diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 2abad3d45..790edaa69 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -333,7 +333,7 @@ def _probe_center_of_mass_constraint(self, current_probe): probe_intensity = xp.abs(current_probe) ** 2 probe_x0, probe_y0 = get_CoM( - probe_intensity, device="cpu" if xp is np else "gpu" + probe_intensity, device=self._device ) shifted_probe = fft_shift( current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp From 7790b227969410de816fbfee096c9f83bc19bf84 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 15 Jun 2023 13:19:12 -0700 Subject: [PATCH 027/362] read_arina start --- py4DSTEM/io/filereaders/__init__.py | 2 +- py4DSTEM/io/filereaders/read_arina.py | 65 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 py4DSTEM/io/filereaders/read_arina.py diff --git a/py4DSTEM/io/filereaders/__init__.py b/py4DSTEM/io/filereaders/__init__.py index d256334a8..44c083856 100644 --- a/py4DSTEM/io/filereaders/__init__.py +++ b/py4DSTEM/io/filereaders/__init__.py @@ -2,4 +2,4 @@ from py4DSTEM.io.filereaders.read_K2 import read_gatan_K2_bin from py4DSTEM.io.filereaders.empad import read_empad from py4DSTEM.io.filereaders.read_mib import load_mib - +from py4DSTEM.io.filereaders.read_arina import read_arina diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py new file mode 100644 index 000000000..86ed2ee9b --- /dev/null +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -0,0 +1,65 @@ +import h5py +import numpy as np +from py4DSTEM.classes import DataCube + +def read_arina(filename, scan_width): + + """ + Args: + filename: str or Path Path to the file + scan_width: x dimension of scan + + Returns: + DataCube + """ + f = h5py.File(filename, "r") + nimages = 0 + + # Count the number of images in all datasets + for dset in f["entry"]["data"]: + nimages = nimages + f["entry"]["data"][dset].shape[0] + height = f["entry"]["data"][dset].shape[1] + width = f["entry"]["data"][dset].shape[2] + dtype = f["entry"]["data"][dset].dtype + + assert ( + nimages % scan_width < 1e-6 + ), "scan_width must be integer multiple of x*y size" + + if dtype.type is np.uint32: + print("Dataset is uint32 but will be converted to uint16") + dtype = np.dtype(np.uint16) + + array_3D = np.empty((nimages, width, height), dtype=dtype) + + image_index = 0 + + for dset in f["entry"]["data"]: + image_index = _processDataSet( + f["entry"]["data"][dset], image_index, array_3D, scan_width + ) + + if f.__bool__(): + f.close() + + scan_height = int(nimages / scan_width) + + datacube = DataCube( + array_3D.reshape( + scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + ) + ) + + return datacube + + +def _processDataSet(dset, start_index, array_3D, scan_width): + image_index = start_index + nimages_dset = dset.shape[0] + + for i in range(nimages_dset): + array_3D[image_index] = dset[i].astype(array_3D.dtype) + + image_index = image_index + 1 + + return image_index From d287e22cc5f3c065cea22828af40276c5c415e8b Mon Sep 17 00:00:00 2001 From: Ben Savitzky Date: Thu, 15 Jun 2023 18:02:21 -0700 Subject: [PATCH 028/362] add file shortcut to gdrive downloader --- py4DSTEM/io/google_drive_downloader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index 00b81d39d..052dbdace 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -20,6 +20,7 @@ 'polycrystal_2D_WS2':'1AWB3-UTPiTR9dgrEkNFD7EJYsKnbEy0y', 'WS2cif':'13zBl6aFExtsz_sew-L0-_ALYJfcgHKjo', 'polymers':'1lK-TAMXN1MpWG0Q3_4vss_uEZgW2_Xh7', + 'vac_probe':'1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', } # collections of files @@ -38,6 +39,7 @@ ('polycrystal_2D_WS2.h5',sample_file_ids['polycrystal_2D_WS2']), ('WS2.cif',sample_file_ids['WS2cif']), ('polymers.h5',sample_file_ids['polymers']), + ('vac_probe.h5',sample_file_ids['vac_probe']), ), } From c70ccac7f8b5dc83ca60ecd21d453959d09fc547 Mon Sep 17 00:00:00 2001 From: Ben Savitzky Date: Thu, 15 Jun 2023 20:46:27 -0700 Subject: [PATCH 029/362] fixes binning datatyping bug --- py4DSTEM/classes/methods/datacube_methods.py | 18 +++++++-- py4DSTEM/preprocess/preprocess.py | 19 ++++++++- test/test_classes/test_datacube.py | 41 ++++++++++++++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 test/test_classes/test_datacube.py diff --git a/py4DSTEM/classes/methods/datacube_methods.py b/py4DSTEM/classes/methods/datacube_methods.py index e6ce58632..bf347e5ae 100644 --- a/py4DSTEM/classes/methods/datacube_methods.py +++ b/py4DSTEM/classes/methods/datacube_methods.py @@ -108,16 +108,26 @@ def crop_R( def bin_Q( self, - N + N, + dtype = None ): """ Bins the data in diffraction space by bin factor N - Accepts: - N (int): the binning factor + Parameters + ---------- + N : int + The binning factor + dtype : a datatype (optional) + Specify the datatype for the output. If not passed, the datatype + is left unchanged + + Returns + ------ + datacube : DataCube """ from py4DSTEM.preprocess import bin_data_diffraction - d = bin_data_diffraction(self,N) + d = bin_data_diffraction(self,N,dtype) return d def pad_Q( diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index de8ff62c1..343c20895 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -208,15 +208,30 @@ def crop_data_real(datacube, crop_Rx_min, crop_Rx_max, crop_Ry_min, crop_Ry_max) return datacube -def bin_data_diffraction(datacube, bin_factor): +def bin_data_diffraction( + datacube, + bin_factor, + dtype=None + ): """ Performs diffraction space binning of data by bin_factor. + + Parameters + ---------- + N : int + The binning factor + dtype : a datatype (optional) + Specify the datatype for the output. If not passed, the datatype + is left unchanged + """ # validate inputs assert(type(bin_factor) is int ), f"Error: binning factor {bin_factor} is not an int." if bin_factor == 1: return datacube + if dtype is None: + dtype = datacube.data.dtype # get shape R_Nx, R_Ny, Q_Nx, Q_Ny = ( @@ -245,7 +260,7 @@ def bin_data_diffraction(datacube, bin_factor): bin_factor, int(Q_Ny / bin_factor), bin_factor, - ).sum(axis=(3, 5)) + ).sum(axis=(3, 5)).astype(dtype) # set dim vectors diff --git a/test/test_classes/test_datacube.py b/test/test_classes/test_datacube.py new file mode 100644 index 000000000..57a225abb --- /dev/null +++ b/test/test_classes/test_datacube.py @@ -0,0 +1,41 @@ +import py4DSTEM +import numpy as np +from os.path import join + +# set filepath +path = join(py4DSTEM._TESTPATH, "small_dm3.dm3") + + + + +class TestDataCube: + + # setup/teardown + def setup_class(cls): + + # Read sim Au datacube + datacube = py4DSTEM.import_file(path) + datacube = py4DSTEM.DataCube( + data=datacube.data.reshape((10,10,512,512)) + ) + cls.datacube = datacube + + # tests + + def test_binning_default_dtype(self): + + dtype = self.datacube.data.dtype + assert(dtype == np.uint16) + + self.datacube.bin_Q(2) + + assert(self.datacube.data.dtype == dtype) + + new_dtype = np.uint32 + self.datacube.bin_Q(2, dtype=new_dtype) + + assert(self.datacube.data.dtype == new_dtype) + assert(self.datacube.data.dtype != dtype) + + pass + From 65ae5272dc8408d75a2ee78d6dace17c1e3a0792 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 09:25:04 -0700 Subject: [PATCH 030/362] handing of single value for com shifts --- py4DSTEM/process/phase/iterative_base_class.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 78a8b59f9..6fe24fa0d 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -142,6 +142,12 @@ def _preprocess_datacube_and_vacuum_probe( datacube: Datacube Resampled and Padded datacube """ + if com_shifts is not None: + if np.isscalar(com_shifts[0]): + com_shifts = ( + np.ones(self._datacube.Rshape) * com_shifts[0], + np.ones(self._datacube.Rshape) * com_shifts[1], + ) if diffraction_intensities_shape is not None: Qx, Qy = datacube.shape[-2:] From 40e69e63844a61cea69aa2f5296a220f161d7df2 Mon Sep 17 00:00:00 2001 From: Ben Savitzky Date: Fri, 16 Jun 2023 10:49:52 -0700 Subject: [PATCH 031/362] bugfix supporting 'root' io syntax --- py4DSTEM/io/read.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 3fe94ca41..e5d227b86 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -71,6 +71,10 @@ def read( filetype = _parse_filetype(filepath) assert filetype == "H5", f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" + # support older `root` input + if datapath is None: + if 'root' in kwargs: + datapath = kwargs['root'] # EMD 1.0 formatted files (py4DSTEM v0.14+) if emd._is_EMD_file(filepath): From 4db3121f4254fd45eb79a1e2920b4ff6894bc60c Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 11:17:42 -0700 Subject: [PATCH 032/362] bug fixes and including in importfile --- py4DSTEM/io/filereaders/read_arina.py | 40 +++++++++++++++++++++------ py4DSTEM/io/importfile.py | 15 +++++----- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 86ed2ee9b..b52dc994e 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -1,17 +1,34 @@ import h5py +import hdf5plugin import numpy as np from py4DSTEM.classes import DataCube +from py4DSTEM.preprocess.utils import bin2D -def read_arina(filename, scan_width): + +def read_arina( + filename, + scan_width, + mem="RAM", + binfactor:int=1, +): """ + File reader for arina 4D-STEM datasets Args: - filename: str or Path Path to the file + filename: str with path to master file scan_width: x dimension of scan + mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is + loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" + leaves the data in storage and creates a memory map which points to + the diffraction patterns, allowing them to be retrieved individually + from storage. + binfactor (int): Diffraction space binning factor for bin-on-load. Returns: - DataCube + DataCube """ + assert mem == "RAM", "ARNIA does not support memory mapping" + f = h5py.File(filename, "r") nimages = 0 @@ -21,7 +38,10 @@ def read_arina(filename, scan_width): height = f["entry"]["data"][dset].shape[1] width = f["entry"]["data"][dset].shape[2] dtype = f["entry"]["data"][dset].dtype - + + width = width//binfactor + height = height//binfactor + assert ( nimages % scan_width < 1e-6 ), "scan_width must be integer multiple of x*y size" @@ -36,7 +56,7 @@ def read_arina(filename, scan_width): for dset in f["entry"]["data"]: image_index = _processDataSet( - f["entry"]["data"][dset], image_index, array_3D, scan_width + f["entry"]["data"][dset], image_index, array_3D, binfactor ) if f.__bool__(): @@ -53,13 +73,15 @@ def read_arina(filename, scan_width): return datacube -def _processDataSet(dset, start_index, array_3D, scan_width): +def _processDataSet(dset, start_index, array_3D, binfactor): image_index = start_index nimages_dset = dset.shape[0] for i in range(nimages_dset): - array_3D[image_index] = dset[i].astype(array_3D.dtype) - + if binfactor == 1: + array_3D[image_index] = dset[i].astype(array_3D.dtype) + else: + array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) + image_index = image_index + 1 - return image_index diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 17b052601..9048e0f7f 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -9,12 +9,11 @@ read_empad, read_dm, read_gatan_K2_bin, - load_mib + load_mib, + read_arina ) - - def import_file( filepath: Union[str, pathlib.Path], mem: Optional[str] = "RAM", @@ -37,6 +36,7 @@ def import_file( from storage. binfactor (int): Diffraction space binning factor for bin-on-load. filetype (str): Used to override automatic filetype detection. + options include "dm", "empad", "gatan_K2_bin", "mib","arina" **kwargs: any additional kwargs are passed to the downstream reader - refer to the individual filetype reader function call signatures and docstrings for more details. @@ -72,7 +72,8 @@ def import_file( "dm", "empad", "gatan_K2_bin", - "mib" + "mib", + "arina", # "kitware_counted", ], "Error: filetype not recognized" @@ -85,10 +86,10 @@ def import_file( # elif filetype == "kitware_counted": # data = read_kitware_counted(filepath, mem, binfactor, metadata=metadata, **kwargs) elif filetype == "mib": - data = load_mib(filepath, mem=mem, binfactor=binfactor,**kwargs) + data = load_mib(filepath, mem=mem, binfactor=binfactor, **kwargs) + elif filetype == "arina": + data = read_arina(filepath, mem=mem, binfactor=binfactor, **kwargs) else: raise Exception("Bad filetype!") return data - - From 5ab9bd703674dfe02b4b37e6679b6674eed64169 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Fri, 16 Jun 2023 15:29:45 -0400 Subject: [PATCH 033/362] dm bin-on-load dtyping bug fix --- py4DSTEM/io/filereaders/read_dm.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_dm.py b/py4DSTEM/io/filereaders/read_dm.py index 153e6d939..60b8975c9 100644 --- a/py4DSTEM/io/filereaders/read_dm.py +++ b/py4DSTEM/io/filereaders/read_dm.py @@ -30,7 +30,7 @@ def read_dm( Metadata instance. kwargs: "dtype": a numpy dtype specifier to use for data binned on load, - defaults to np.float32 + defaults to the data's current dtype Returns: DataCube if a 4D dataset is found, else an ND Array @@ -96,7 +96,7 @@ def read_dm( elif Q_pixel_units == "1/nm": Q_pixel_units = "A^-1" Q_pixel_size /= 10 - + pixel_size_found = True except Exception as err: pass @@ -108,10 +108,12 @@ def read_dm( if binfactor == 1: _data = dmFile.getDataset(dataset_index)["data"] else: + # get a memory map + _mmap = dmFile.getMemmap(dataset_index) + # get the dtype for the binned data - dtype = kwargs.get("dtype", np.float32) + dtype = kwargs.get("dtype", _mmap[0,0].dtype) - _mmap = dmFile.getMemmap(dataset_index) if titan_shape is not None: # NCEM TitanX tags were found _mmap = np.reshape(_mmap, titan_shape + _mmap.shape[-2:]) @@ -120,7 +122,7 @@ def read_dm( _mmap.shape[2] // binfactor, _mmap.shape[3] // binfactor, ) - _data = np.zeros(new_shape) + _data = np.zeros(new_shape, dtype=dtype) for rx, ry in tqdmnd(*_data.shape[:2]): _data[rx, ry] = bin2D(_mmap[rx, ry], binfactor, dtype=dtype) From 8d18c70ea0f2745e013e12ac3d2cad8a68e7b7e2 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 12:55:43 -0700 Subject: [PATCH 034/362] hdf5plugin dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 06c85ea70..3dc0b9e5a 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ 'numpy >= 1.19', 'scipy >= 1.5.2', 'h5py >= 3.2.0', + 'hdf5plugin >= 4.1.3', 'ncempy >= 1.8.1', 'matplotlib >= 3.2.2', 'scikit-image >= 0.17.2', From 7641d4d1a6cd892c6521223d15a44ac9f7bd5a42 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 14:45:14 -0700 Subject: [PATCH 035/362] switching to corner-centered probes --- py4DSTEM/process/phase/__init__.py | 28 +-- .../process/phase/iterative_base_class.py | 181 ++++++++---------- .../iterative_ptychographic_constraints.py | 36 ++-- .../iterative_singleslice_ptychography.py | 88 +++++---- py4DSTEM/process/phase/utils.py | 63 +++--- py4DSTEM/process/utils/utils.py | 15 +- 6 files changed, 197 insertions(+), 214 deletions(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index c2e141399..207e44b56 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -1,22 +1,14 @@ +# fmt: off + _emd_hook = True from py4DSTEM.process.phase.iterative_dpc import DPCReconstruction -from py4DSTEM.process.phase.iterative_mixedstate_ptychography import ( - MixedstatePtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_multislice_ptychography import ( - MultislicePtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import ( - OverlapMagneticTomographicReconstruction, -) -from py4DSTEM.process.phase.iterative_overlap_tomography import ( - OverlapTomographicReconstruction, -) +from py4DSTEM.process.phase.iterative_mixedstate_ptychography import MixedstatePtychographicReconstruction +from py4DSTEM.process.phase.iterative_multislice_ptychography import MultislicePtychographicReconstruction +from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import OverlapMagneticTomographicReconstruction +from py4DSTEM.process.phase.iterative_overlap_tomography import OverlapTomographicReconstruction from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction -from py4DSTEM.process.phase.iterative_simultaneous_ptychography import ( - SimultaneousPtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_singleslice_ptychography import ( - SingleslicePtychographicReconstruction, -) +from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction +from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction + +# fmt: on diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 78a8b59f9..171493fc0 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -143,6 +143,13 @@ def _preprocess_datacube_and_vacuum_probe( Resampled and Padded datacube """ + if com_shifts is not None: + if np.isscalar(com_shifts[0]): + com_shifts = ( + np.ones(self._datacube.Rshape) * com_shifts[0], + np.ones(self._datacube.Rshape) * com_shifts[1], + ) + if diffraction_intensities_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = diffraction_intensities_shape @@ -527,7 +534,7 @@ def _solve_for_center_of_mass_relative_rotation( warnings.warn( ( "Best fit rotation forced to " - f"{str(np.round(force_com_rotation))} degrees." + f"{force_com_rotation:.0f} degrees." ), UserWarning, ) @@ -697,12 +704,7 @@ def _solve_for_center_of_mass_relative_rotation( _rotation_best_rad = rotation_angles_rad[ind_min] if self._verbose: - print( - ( - "Best fit rotation = " - f"{str(np.round(rotation_best_deg))} degrees." - ) - ) + print(("Best fit rotation = " f"{rotation_best_deg:.0f} degrees.")) if plot_rotation: figsize = kwargs.get("figsize", (8, 2)) @@ -857,12 +859,7 @@ def _solve_for_center_of_mass_relative_rotation( self._rotation_angles_deg = rotation_angles_deg # Print summary if self._verbose: - print( - ( - "Best fit rotation = " - f"{str(np.round(rotation_best_deg))} degrees." - ) - ) + print(("Best fit rotation = " f"{rotation_best_deg:.0f} degrees.")) if _rotation_best_transpose: print("Diffraction intensities should be transposed.") else: @@ -1329,11 +1326,6 @@ def _set_polar_parameters(self, parameters: dict): ---------- parameters: dict Mapping from aberration symbols to their corresponding values. - - Mutates - ------- - self._polar_parameters: dict - Updated polar aberrations dictionary """ for symbol, value in parameters.items(): @@ -1359,11 +1351,6 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): Input probe positions in Å. If None, a raster scan using experimental parameters is constructed. - Mutates - ------- - self._object_padding_px: np.ndarray - Object array padding in pixels - Returns ------- positions_in_px: (J,2) np.ndarray @@ -1412,74 +1399,17 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): positions -= np.min(positions, axis=0) if self._object_padding_px is None: - self._object_padding_px = self._region_of_interest_shape / 2 - positions += self._object_padding_px + float_padding = self._region_of_interest_shape / 2 + self._object_padding_px = (float_padding, float_padding) + positions[:, 0] += self._object_padding_px[0][0] + positions[:, 1] += self._object_padding_px[1][0] return positions - def _wrapped_indices_2D_window( - self, - center_position: np.ndarray, - window_shape: Sequence[int], - array_shape: Sequence[int], - ): - """ - Computes periodic indices for a window_shape probe centered at center_position, - in object of size array_shape. - - Parameters - ---------- - center_position: (2,) np.ndarray - The window center positions in pixels - window_shape: (2,) Sequence[int] - The pixel dimensions of the window - array_shape: (2,) Sequence[int] - The pixel dimensions of the array the window will be embedded in - - Returns - ------- - window_indices: length-2 tuple of - The 2D indices of the window - """ - - asnumpy = self._asnumpy - sx, sy = array_shape - nx, ny = window_shape - - cx, cy = np.round(asnumpy(center_position)).astype(int) - ox, oy = (cx - nx // 2, cy - ny // 2) - - return np.ix_(np.arange(ox, ox + nx) % sx, np.arange(oy, oy + ny) % sy) - - def _sum_overlapping_patches(self, patches: np.ndarray): - """ - Sum overlapping patches defined into object shaped array - - Parameters - ---------- - patches: (Rx*Ry,Sx,Sy) np.ndarray - Patches to sum - - Returns - ------- - out_array: (Px,Py) np.ndarray - Summed array - """ - xp = self._xp - positions = self._positions_px - patch_shape = self._region_of_interest_shape - array_shape = self._object_shape - - out_array = xp.zeros(array_shape, patches.dtype) - for ind, pos in enumerate(positions): - indices = self._wrapped_indices_2D_window(pos, patch_shape, array_shape) - out_array[indices] += patches[ind] - - return out_array - def _sum_overlapping_patches_bincounts_base(self, patches: np.ndarray): """ Base bincouts overlapping patches sum function, operating on real-valued arrays. + Note this assumes the probe is corner-centered. Parameters ---------- @@ -1496,8 +1426,8 @@ def _sum_overlapping_patches_bincounts_base(self, patches: np.ndarray): y0 = xp.round(self._positions_px[:, 1]).astype("int") roi_shape = self._region_of_interest_shape - x_ind = xp.round(xp.arange(roi_shape[0]) - roi_shape[0] / 2).astype("int") - y_ind = xp.round(xp.arange(roi_shape[1]) - roi_shape[1] / 2).astype("int") + x_ind = xp.fft.fftfreq(roi_shape[0], d=1 / roi_shape[0]).astype("int") + y_ind = xp.fft.fftfreq(roi_shape[1], d=1 / roi_shape[1]).astype("int") flat_weights = patches.ravel() indices = ( @@ -1539,6 +1469,7 @@ def _sum_overlapping_patches_bincounts(self, patches: np.ndarray): def _extract_vectorized_patch_indices(self): """ Sets the vectorized row/col indices used for the overlap projection + Note this assumes the probe is corner-centered. Returns ------- @@ -1552,8 +1483,8 @@ def _extract_vectorized_patch_indices(self): y0 = xp.round(self._positions_px[:, 1]).astype("int") roi_shape = self._region_of_interest_shape - x_ind = xp.round(xp.arange(roi_shape[0]) - roi_shape[0] / 2).astype("int") - y_ind = xp.round(xp.arange(roi_shape[1]) - roi_shape[1] / 2).astype("int") + x_ind = xp.fft.fftfreq(roi_shape[0], d=1 / roi_shape[0]).astype("int") + y_ind = xp.fft.fftfreq(roi_shape[1], d=1 / roi_shape[1]).astype("int") obj_shape = self._object_shape vectorized_patch_indices_row = ( @@ -1725,8 +1656,7 @@ def tune_angle_and_defocus( fig = plt.figure(figsize=figsize) - progress_bar = kwargs.get("progress_bar", False) - kwargs.pop("progress_bar", None) + progress_bar = kwargs.pop("progress_bar", False) # run loop and plot along the way self._verbose = False for flat_index, (angle, defocus) in enumerate( @@ -1994,7 +1924,7 @@ def _return_fourier_probe( ): """ Returns complex fourier probe shifted to center of array from - complex real space probe in center + corner-centered complex real space probe Parameters ---------- @@ -2013,16 +1943,61 @@ def _return_fourier_probe( else: probe = xp.asarray(probe, dtype=xp.complex64) - return xp.fft.fftshift( - xp.fft.fft2(xp.fft.ifftshift(probe, axes=(-2, -1))), axes=(-2, -1) - ) + return xp.fft.fftshift(xp.fft.fft2(probe), axes=(-2, -1)) + + def _return_fourier_probe_from_centered_probe( + self, + probe=None, + ): + """ + Returns complex fourier probe shifted to center of array from + centered complex real space probe + + Parameters + ---------- + probe: complex array, optional + if None is specified, uses self._probe + + Returns + ------- + fourier_probe: np.ndarray + Fourier-transformed and center-shifted probe. + """ + xp = self._xp + return self._return_fourier_probe(xp.fft.ifftshift(probe, axes=(-2, -1))) + + def _return_centered_probe( + self, + probe=None, + ): + """ + Returns complex probe centered in middle of the array. + + Parameters + ---------- + probe: complex array, optional + if None is specified, uses self._probe + + Returns + ------- + centered_probe: np.ndarray + Center-shifted probe. + """ + xp = self._xp + + if probe is None: + probe = self._probe + else: + probe = xp.asarray(probe, dtype=xp.complex64) + + return xp.fft.fftshift(probe, axes=(-2, -1)) def _return_object_fft( self, obj=None, ): """ - Returns obj fft shifted to center of array + Returns absolute value of obj fft shifted to center of array Parameters ---------- @@ -2040,7 +2015,7 @@ def _return_object_fft( obj = self._object obj = self._crop_rotate_object_fov(asnumpy(obj)) - return np.abs(np.fft.fftshift(np.fft.fft2(obj))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) def show_fourier_probe( self, @@ -2131,13 +2106,21 @@ def show_object_fft(self, obj=None, **kwargs): @property def probe_fourier(self): """Current probe estimate in Fourier space""" - if not hasattr(self, "_probe"): return None asnumpy = self._asnumpy return asnumpy(self._return_fourier_probe(self._probe)) + @property + def probe_centered(self): + """Current probe estimate shifted to the center""" + if not hasattr(self, "_probe"): + return None + + asnumpy = self._asnumpy + return asnumpy(self._return_centered_probe(self._probe)) + @property def object_fft(self): """Fourier transform of current object estimate""" @@ -2180,7 +2163,7 @@ def positions(self): return asnumpy(positions) @property - def _object_cropped(self): + def object_cropped(self): """cropped and rotated object""" return self._crop_rotate_object_fov(self._object) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 790edaa69..10b24eb78 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -315,7 +315,7 @@ def _object_denoise_tv_chambolle( def _probe_center_of_mass_constraint(self, current_probe): """ Ptychographic center of mass constraint. - Used for centering probe intensity. + Used for centering corner-centered probe intensity. Parameters -------- @@ -329,15 +329,12 @@ def _probe_center_of_mass_constraint(self, current_probe): """ xp = self._xp - probe_center = xp.array(self._region_of_interest_shape) / 2 probe_intensity = xp.abs(current_probe) ** 2 probe_x0, probe_y0 = get_CoM( - probe_intensity, device=self._device - ) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp + probe_intensity, device=self._device, corner_centered=True ) + shifted_probe = fft_shift(current_probe, -xp.array([probe_x0, probe_y0]), xp) return shifted_probe @@ -352,13 +349,14 @@ def _probe_radial_symmetrization_constraint_base( sx, sy = current_probe.shape if center is None: - center = (sx // 2, sy // 2) + center = (0, 0) if num_bins is None: num_bins = np.maximum(sx, sy) * 2 + 1 cx, cy = center - X, Y = xp.ogrid[0:sx, 0:sy] + X = xp.fft.fftfreq(sx, d=1 / sx)[:, None] + Y = xp.fft.fftfreq(sy, d=1 / sy)[None] r = xp.hypot(X - cx, Y - cy) rbin = (num_bins * r / r.max()).astype("int") @@ -383,7 +381,7 @@ def _probe_radial_symmetrization_constraint( xp = self._xp current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) - fourier_probe = self._return_fourier_probe(current_probe) + fourier_probe = xp.fft.fft2(current_probe) fourier_probe_real = fourier_probe.real.copy() fourier_probe_imag = fourier_probe.imag.copy() @@ -396,7 +394,7 @@ def _probe_radial_symmetrization_constraint( ) fourier_probe = fourier_probe_real + 1.0j * fourier_probe_imag - current_probe = xp.fft.ifftshift(xp.fft.ifft2(xp.fft.fftshift(fourier_probe))) + current_probe = xp.fft.ifft2(fourier_probe) current_probe *= xp.sqrt(current_probe_sum / np.sum(np.abs(current_probe) ** 2)) return current_probe @@ -427,13 +425,12 @@ def _probe_amplitude_constraint( probe_intensity = xp.abs(current_probe) ** 2 current_probe_sum = xp.sum(probe_intensity) - x = xp.linspace(-1 / 2, 1 / 2, current_probe.shape[0]) - y = xp.linspace(-1 / 2, 1 / 2, current_probe.shape[1]) - xa, ya = xp.meshgrid(x, y, indexing="ij") - ra = xp.sqrt(xa**2 + ya**2) - relative_radius + X = xp.fft.fftfreq(current_probe.shape[0])[:, None] + Y = xp.fft.fftfreq(current_probe.shape[1])[None] + r = xp.hypot(X, Y) - relative_radius sigma = np.sqrt(np.pi) / relative_width - tophat_mask = 0.5 * (1 - erf(sigma * ra / (1 - ra**2))) + tophat_mask = 0.5 * (1 - erf(sigma * r / (1 - r**2))) updated_probe = current_probe * tophat_mask updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) @@ -483,7 +480,6 @@ def _probe_fourier_amplitude_constraint( sigma = np.sqrt(np.pi) / relative_width tophat_mask = 0.5 * (1 - erf(sigma * qra / (1 - qra**2))) - updated_probe = xp.fft.ifft2(current_probe_fft * tophat_mask) updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) normalization = xp.sqrt(current_probe_sum / updated_probe_sum) @@ -520,19 +516,21 @@ def _probe_residual_aberration_filtering_constraint( known_aberrations_array = self._known_aberrations_array gaussian_filter_sigma /= self._reciprocal_sampling[0] - fourier_probe = self._return_fourier_probe(current_probe) + fourier_probe = xp.fft.fft2(current_probe) if fix_amplitude: fourier_probe_abs = xp.abs(fourier_probe) fourier_probe *= xp.conjugate(known_aberrations_array) - fourier_probe = gaussian_filter(fourier_probe, gaussian_filter_sigma) + fourier_probe = gaussian_filter( + fourier_probe, gaussian_filter_sigma, mode="wrap" + ) fourier_probe *= known_aberrations_array if fix_amplitude: fourier_probe_angle = xp.angle(fourier_probe) fourier_probe = fourier_probe_abs * xp.exp(1.0j * fourier_probe_angle) - current_probe = xp.fft.ifftshift(xp.fft.ifft2(xp.fft.fftshift(fourier_probe))) + current_probe = xp.fft.ifft2(fourier_probe) return current_probe diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index bccc54074..1cf9e4e44 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -327,16 +327,16 @@ def preprocess( self._positions_px = self._calculate_scan_positions_in_pixels( self._scan_positions ) - # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((p, q), dtype=xp.float32) @@ -379,18 +379,16 @@ def preprocess( self._vacuum_probe_intensity, dtype=xp.float32 ) probe_x0, probe_y0 = get_CoM( - self._vacuum_probe_intensity, device=self._device + self._vacuum_probe_intensity, + device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) - self._probe = ( ComplexProbe( gpts=self._region_of_interest_shape, @@ -438,8 +436,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe, self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -462,7 +458,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -1578,11 +1574,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -1696,12 +1692,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -1767,19 +1771,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -1923,12 +1929,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -1984,16 +1998,25 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") + else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2001,9 +2024,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 621223b60..63377be75 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -15,46 +15,26 @@ from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from scipy.ndimage import gaussian_filter +# fmt: off + #: Symbols for the polar representation of all optical aberrations up to the fifth order. polar_symbols = ( - "C10", - "C12", - "phi12", - "C21", - "phi21", - "C23", - "phi23", - "C30", - "C32", - "phi32", - "C34", - "phi34", - "C41", - "phi41", - "C43", - "phi43", - "C45", - "phi45", - "C50", - "C52", - "phi52", - "C54", - "phi54", - "C56", - "phi56", + "C10", "C12", "phi12", + "C21", "phi21", "C23", "phi23", + "C30", "C32", "phi32", "C34", "phi34", + "C41", "phi41", "C43", "phi43", "C45", "phi45", + "C50", "C52", "phi52", "C54", "phi54", "C56", "phi56", ) #: Aliases for the most commonly used optical aberrations. polar_aliases = { - "defocus": "C10", - "astigmatism": "C12", - "astigmatism_angle": "phi12", - "coma": "C21", - "coma_angle": "phi21", - "Cs": "C30", - "C5": "C50", + "defocus": "C10", "astigmatism": "C12", "astigmatism_angle": "phi12", + "coma": "C21", "coma_angle": "phi21", + "Cs": "C30", + "C5": "C50", } +# fmt: on ### Probe functions @@ -81,6 +61,8 @@ class ComplexProbe: Device to perform calculations on. Must be either 'cpu' or 'gpu' rolloff: float, optional Tapers the cutoff edge over the given angular range [mrad]. + vacuum_probe_intensity: np.ndarray, optional + Squared of corner-centered aperture amplitude to use, instead of semiangle_cutoff + rolloff focal_spread: float, optional The 1/e width of the focal spread due to chromatic aberration and lens current instability [Å]. angular_spread: float, optional @@ -180,7 +162,7 @@ def evaluate_aperture( self._vacuum_probe_intensity, dtype=xp.float32 ) vacuum_probe_amplitude = xp.sqrt(xp.maximum(vacuum_probe_intensity, 0)) - return xp.fft.ifftshift(vacuum_probe_amplitude) + return vacuum_probe_amplitude if self._semiangle_cutoff == xp.inf: return xp.ones_like(alpha) @@ -432,9 +414,9 @@ def polar_coordinates(self, x, y): return alpha, phi def build(self): - """Builds complex probe in the center of the region of interest.""" + """Builds corner-centered complex probe in the center of the region of interest.""" xp = self._xp - array = xp.fft.fftshift(xp.fft.ifft2(self._evaluate_ctf())) + array = xp.fft.ifft2(self._evaluate_ctf()) array = array / xp.sqrt((xp.abs(array) ** 2).sum()) self._array = array return self @@ -448,7 +430,7 @@ def visualize(self, **kwargs): kwargs.pop("cmap", None) plt.imshow( - asnumpy(xp.abs(self._array) ** 2), + asnumpy(xp.abs(xp.fft.ifftshift(self._array)) ** 2), cmap=cmap, **kwargs, ) @@ -1286,15 +1268,20 @@ def project_vector_field_divergence(vector_field, spacings=(1, 1, 1), xp=np): grad_p = compute_gradient(p, spacings, xp=xp) return vector_field - grad_p + # Nesterov acceleration functions # https://blogs.princeton.edu/imabandit/2013/04/01/acceleratedgradientdescent/ + @functools.cache def nesterov_lambda(one_indexed_iter_num): if one_indexed_iter_num == 0: return 0 - return (1+np.sqrt(1+4*nesterov_lambda(one_indexed_iter_num-1)**2))/2 + return (1 + np.sqrt(1 + 4 * nesterov_lambda(one_indexed_iter_num - 1) ** 2)) / 2 + def nesterov_gamma(zero_indexed_iter_num): one_indexed_iter_num = zero_indexed_iter_num + 1 - return (1-nesterov_lambda(one_indexed_iter_num))/nesterov_lambda(one_indexed_iter_num+1) + return (1 - nesterov_lambda(one_indexed_iter_num)) / nesterov_lambda( + one_indexed_iter_num + 1 + ) diff --git a/py4DSTEM/process/utils/utils.py b/py4DSTEM/process/utils/utils.py index 29badd389..1df4e78c5 100644 --- a/py4DSTEM/process/utils/utils.py +++ b/py4DSTEM/process/utils/utils.py @@ -174,21 +174,24 @@ def make_Fourier_coords2D(Nx, Ny, pixelSize=1): qy, qx = np.meshgrid(qy, qx) return qx, qy - -def get_CoM(ar, device = "cpu"): +def get_CoM(ar, device="cpu", corner_centered=False): """ Finds and returns the center of mass of array ar. + If corner_centered is True, uses fftfreq for indices. """ if device == "cpu": xp = np - elif device == "gpu": xp = cp - ar = xp.asarray(ar) - + ar = xp.asarray(ar) nx, ny = ar.shape - ry, rx = xp.meshgrid(xp.arange(ny), xp.arange(nx)) + + if corner_centered: + ry, rx = xp.meshgrid(xp.fft.fftfreq(ny, 1 / ny), xp.fft.fftfreq(nx, 1 / nx)) + else: + ry, rx = xp.meshgrid(xp.arange(ny), xp.arange(nx)) + tot_intens = xp.sum(ar) xCoM = xp.sum(rx * ar) / tot_intens yCoM = xp.sum(ry * ar) / tot_intens From e4f5af0bfa8a5aab9058403083a5f82f05341273 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 14:46:17 -0700 Subject: [PATCH 036/362] removing merge conflict duplicate lines --- py4DSTEM/process/phase/iterative_base_class.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index c6a151e5f..b33ea78a9 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -149,13 +149,6 @@ def _preprocess_datacube_and_vacuum_probe( np.ones(self._datacube.Rshape) * com_shifts[1], ) - if com_shifts is not None: - if np.isscalar(com_shifts[0]): - com_shifts = ( - np.ones(self._datacube.Rshape) * com_shifts[0], - np.ones(self._datacube.Rshape) * com_shifts[1], - ) - if diffraction_intensities_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = diffraction_intensities_shape From dca06e52e3bea640f282ed38290e8e69d69fe038 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 15:21:29 -0700 Subject: [PATCH 037/362] corner-centered probe multislice --- .../iterative_multislice_ptychography.py | 95 ++++++++++++------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index c0e73e13b..ce8d13325 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -421,13 +421,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((self._num_slices, p, q), dtype=xp.float32) @@ -470,14 +471,13 @@ def preprocess( self._vacuum_probe_intensity, dtype=xp.float32 ) probe_x0, probe_y0 = get_CoM( - self._vacuum_probe_intensity, device=self._device + self._vacuum_probe_intensity, + device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -530,8 +530,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._propagator_arrays = self._precompute_propagator_arrays( self._region_of_interest_shape, @@ -562,7 +560,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -577,7 +575,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2090,11 +2088,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -2215,12 +2213,21 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2287,19 +2294,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2445,12 +2454,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2505,16 +2522,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2522,9 +2547,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert @@ -2621,6 +2643,7 @@ def show_transmitted_probe( """ xp = self._xp + asnumpy = self._asnumpy transmitted_probe_intensities = xp.sum( xp.abs(self._transmitted_probes) ** 2, axis=(-2, -1) @@ -2633,7 +2656,7 @@ def show_transmitted_probe( ] mean_transmitted = self._transmitted_probes.mean(0) probes = [ - self._asnumpy(probe) + asnumpy(self._return_centered_probe(probe)) for probe in [ mean_transmitted, min_intensity_transmitted, @@ -2648,7 +2671,7 @@ def show_transmitted_probe( if plot_fourier_probe: bottom_row = [ - self._asnumpy(self._return_fourier_probe(probe)) + asnumpy(self._return_fourier_probe(probe)) for probe in [ mean_transmitted, min_intensity_transmitted, @@ -2988,4 +3011,4 @@ def _return_object_fft( obj = np.angle(obj) obj = self._crop_rotate_object_fov(np.sum(obj, axis=0)) - return np.abs(np.fft.fftshift(np.fft.fft2(obj))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) From 2b203eb3e3230d53509c1056806e2e7e30c0938e Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 16:22:27 -0700 Subject: [PATCH 038/362] corner-centered probe mixedstate --- .../iterative_mixedstate_ptychography.py | 112 ++++++++++-------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index ff32f5b49..2d595fab1 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -347,13 +347,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((p, q), dtype=xp.float32) @@ -400,12 +401,10 @@ def preprocess( self._vacuum_probe_intensity, device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -476,8 +475,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe[0], self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -500,7 +497,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe[0]), + self.probe_centered[0], vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -536,7 +533,7 @@ def preprocess( ) ax1.set_ylabel("x [A]") ax1.set_xlabel("y [A]") - ax1.set_title("Initial Probe") + ax1.set_title("Initial Probe[0]") ax2.imshow( asnumpy(probe_overlap), @@ -1021,8 +1018,8 @@ def _adjoint( def _probe_center_of_mass_constraint(self, current_probe): """ - Ptychographic threshold constraint. - Used for avoiding the scaling ambiguity between probe and object. + Ptychographic center of mass constraint. + Used for centering corner-centered probe intensity. Parameters -------- @@ -1035,15 +1032,12 @@ def _probe_center_of_mass_constraint(self, current_probe): Constrained probe estimate """ xp = self._xp - asnumpy = self._asnumpy - - probe_center = xp.array(self._region_of_interest_shape) / 2 - probe_intensity = asnumpy(xp.abs(current_probe[0]) ** 2) + probe_intensity = xp.abs(current_probe[0]) ** 2 - probe_x0, probe_y0 = get_CoM(probe_intensity) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp + probe_x0, probe_y0 = get_CoM( + probe_intensity, device=self._device, corner_centered=True ) + shifted_probe = fft_shift(current_probe, -xp.array([probe_x0, probe_y0]), xp) return shifted_probe @@ -1063,10 +1057,9 @@ def _probe_orthogonalization_constraint(self, current_probe): Orthogonalized probe estimate """ xp = self._xp + shape = current_probe.shape - return orthogonalize(current_probe.reshape((self._num_probes, -1)), xp).reshape( - current_probe.shape - ) + return orthogonalize(current_probe.reshape((shape[0], -1)), xp).reshape(shape) def _constraints( self, @@ -1663,11 +1656,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -1779,12 +1772,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -1849,20 +1850,22 @@ def _visualize_last_iteration( probe_array = Complex2RGB( self.probe_fourier[0], hue_start=hue_start, invert=invert ) - ax.set_title("Reconstructed Fourier probe") + ax.set_title("Reconstructed Fourier probe[0]") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe[0], hue_start=hue_start, invert=invert ) - ax.set_title("Reconstructed probe") + ax.set_title("Reconstructed probe[0]") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2006,12 +2009,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2066,16 +2077,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]][0])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]][0] + ) + ), hue_start=hue_start, invert=invert, ) - ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_title(f"Iter: {grid_range[n]} Fourier probe[0]") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]][0], hue_start=hue_start, invert=invert ) - ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_title(f"Iter: {grid_range[n]} probe[0]") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2083,9 +2102,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert From 7e4dd35064e89bf880edc668ec9cf362b1827834 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 16:41:35 -0700 Subject: [PATCH 039/362] corner-centered probe simultaneous --- .../iterative_simultaneous_ptychography.py | 77 +++++++------------ 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index c2a6f047f..e872bc42e 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -593,13 +593,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": object_e = xp.zeros((p, q), dtype=xp.float32) @@ -647,12 +648,10 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -704,8 +703,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe, self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -728,7 +725,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2173,34 +2170,6 @@ def _adjoint( return current_object, current_probe - def _probe_center_of_mass_constraint(self, current_probe): - """ - Ptychographic threshold constraint. - Used for avoiding the scaling ambiguity between probe and object. - - Parameters - -------- - current_probe: np.ndarray - Current probe estimate - - Returns - -------- - constrained_probe: np.ndarray - Constrained probe estimate - """ - xp = self._xp - asnumpy = self._asnumpy - - probe_center = xp.array(self._region_of_interest_shape) / 2 - probe_intensity = asnumpy(xp.abs(current_probe) ** 2) - - probe_x0, probe_y0 = get_CoM(probe_intensity) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp - ) - - return shifted_probe - def _constraints( self, current_object, @@ -2885,14 +2854,14 @@ def reconstruct( asnumpy(self._object[1].copy()), ) ) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result if a0 < warmup_iter: self.object = (asnumpy(self._object[0]), None) else: self.object = (asnumpy(self._object[0]), asnumpy(self._object[1])) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -3019,12 +2988,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -3111,19 +3088,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) From 47f0a41f0f2e7dba45408a16d506e59530ee3b95 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:02:43 -0700 Subject: [PATCH 040/362] corner-centered probe overlap tomography --- .../iterative_overlap_magnetic_tomography.py | 23 ++-- .../phase/iterative_overlap_tomography.py | 115 ++++++++---------- 2 files changed, 62 insertions(+), 76 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index aaede8dfc..2a11f87b5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -602,8 +602,9 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px_all, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px_all, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( "int" ) @@ -654,12 +655,10 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -717,8 +716,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._slice_thicknesses = np.tile( self._object_shape[1] * self.sampling[1] / self._num_slices, @@ -795,7 +792,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -810,7 +807,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2485,11 +2482,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -3030,7 +3027,7 @@ def _return_object_fft( rotated_3d_obj.sum(0), angle=None, x_lims=x_lims, y_lims=y_lims ) - return np.abs(np.fft.fftshift(np.fft.fft2(rotated_object))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(rotated_object)))) def show_object_fft( self, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index ac98738dc..dd5eb2be8 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -254,40 +254,6 @@ def _propagate_array(self, array: np.ndarray, propagator_array: np.ndarray): return xp.fft.ifft2(xp.fft.fft2(array) * propagator_array) - def _expand_or_project_sliced_object(self, array: np.ndarray, output_z): - """ - OLD Version - - Expands supersliced object or projects voxel-sliced object. - - Parameters - ---------- - array: np.ndarray - 3D array to expand/project - output_z: int - Output_dimension to expand/project array to. - If output_z > array.shape[0] array is expanded, else it's projected - - Returns - ------- - expanded_or_projected_array: np.ndarray - expanded or projected array - """ - zoom = self._zoom - input_z = array.shape[0] - - return ( - zoom( - array, - (output_z / input_z, 1, 1), - order=0, - mode="nearest", - grid_mode=True, - ) - * input_z - / output_z - ) - def _project_sliced_object(self, array: np.ndarray, output_z): """ Expands supersliced object or projects voxel-sliced object. @@ -545,8 +511,9 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px_all, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px_all, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( "int" ) @@ -601,8 +568,8 @@ def preprocess( shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -660,8 +627,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._slice_thicknesses = np.tile( self._object_shape[1] * self.sampling[1] / self._num_slices, @@ -741,7 +706,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -756,7 +721,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2240,11 +2205,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -2440,12 +2405,21 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2509,19 +2483,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2686,12 +2662,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2745,16 +2729,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2762,9 +2754,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert @@ -2909,7 +2898,7 @@ def _return_object_fft( rotated_3d_obj.sum(0), angle=None, x_lims=x_lims, y_lims=y_lims ) - return np.abs(np.fft.fftshift(np.fft.fft2(rotated_object))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(rotated_object)))) def show_object_fft( self, From 1ac6d0a2b8e06453ba11afea08db61f2493cb543 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:05:55 -0700 Subject: [PATCH 041/362] some flake8 gotchas --- py4DSTEM/process/phase/iterative_base_class.py | 1 - .../process/phase/iterative_overlap_magnetic_tomography.py | 1 - py4DSTEM/process/phase/iterative_overlap_tomography.py | 3 --- 3 files changed, 5 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index b33ea78a9..5a149f14c 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -3,7 +3,6 @@ """ import warnings -from typing import Sequence import matplotlib.pyplot as plt import numpy as np diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 2a11f87b5..3c33d46f5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1581,7 +1581,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): Constrained object estimate """ gaussian_filter = self._gaussian_filter - xp = self._xp gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index dd5eb2be8..4a64f17af 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -564,8 +564,6 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, -probe_x0, @@ -1456,7 +1454,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): Constrained object estimate """ gaussian_filter = self._gaussian_filter - xp = self._xp gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) From 316ba9b8a9596d7beead9cf82fc7b8cb1bc11b91 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:09:41 -0700 Subject: [PATCH 042/362] supporting old padding format --- py4DSTEM/process/phase/iterative_base_class.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 5a149f14c..e17b677a1 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -1399,6 +1399,12 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): if self._object_padding_px is None: float_padding = self._region_of_interest_shape / 2 self._object_padding_px = (float_padding, float_padding) + elif np.isscalar(self._object_padding_px[0]): + self._object_padding_px = ( + (self._object_padding_px[0],)*2, + (self._object_padding_px[1],)*2 + ) + positions[:, 0] += self._object_padding_px[0][0] positions[:, 1] += self._object_padding_px[1][0] From d95c706930d7a4b1ba55386eceda3a86b0a47d10 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:23:37 -0700 Subject: [PATCH 043/362] comment out leftover debugging print statement --- py4DSTEM/io/legacy/read_legacy_13.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/legacy/read_legacy_13.py b/py4DSTEM/io/legacy/read_legacy_13.py index ebf86d5c3..a325be2d9 100644 --- a/py4DSTEM/io/legacy/read_legacy_13.py +++ b/py4DSTEM/io/legacy/read_legacy_13.py @@ -257,7 +257,7 @@ def _get_v13_class(grp): 'QPoints' : QPoints, 'BraggVectors' : BraggVectors } - print(grp) + #print(grp) if 'py4dstem_class' in grp.attrs: classname = grp.attrs['py4dstem_class'] elif 'emd_group_type' in grp.attrs: From 5a02566b8622a0d9ba1456b84ee537b2f5febdde Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:25:37 -0700 Subject: [PATCH 044/362] adding show_complex to top-level imports --- py4DSTEM/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index dc4f765ae..3c7803666 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -47,7 +47,7 @@ # functions from emdfile import print_h5_tree -from py4DSTEM.visualize import show +from py4DSTEM.visualize import show, show_complex from py4DSTEM.io import import_file,read,save from py4DSTEM.utils.configuration_checker import check_config From 9c3913bf85ab2fccb6ac4cf8d4457ce8dc57022d Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 08:29:09 -0700 Subject: [PATCH 045/362] updates for file parser and dtype --- py4DSTEM/io/filereaders/read_arina.py | 8 ++++++- py4DSTEM/io/parsefiletype.py | 32 ++++++++++++++++++++++++--- py4DSTEM/io/read.py | 6 ++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index b52dc994e..4d0b605fd 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -10,6 +10,7 @@ def read_arina( scan_width, mem="RAM", binfactor:int=1, + dtype_bin:float=None, ): """ @@ -23,6 +24,8 @@ def read_arina( the diffraction patterns, allowing them to be retrieved individually from storage. binfactor (int): Diffraction space binning factor for bin-on-load. + dtype_bin(float): specify datatype for bin on load if need something + other than uint16 Returns: DataCube @@ -50,7 +53,10 @@ def read_arina( print("Dataset is uint32 but will be converted to uint16") dtype = np.dtype(np.uint16) - array_3D = np.empty((nimages, width, height), dtype=dtype) + if dtype_bin: + array_3D = np.empty((nimages, width, height), dtype=dtype_bin) + else: + array_3D = np.empty((nimages, width, height), dtype=dtype) image_index = 0 diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index 5903ce814..b2889511a 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -1,9 +1,13 @@ # File parser utility from os.path import splitext +import py4DSTEM.io.legacy as legacy +import emdfile as emd +import h5py def _parse_filetype(fp): - """ Accepts a path to a data file, and returns the file type as a string. + """ + Accepts a path to a data file, and returns the file type as a string. """ _, fext = splitext(fp) fext = fext.lower() @@ -13,7 +17,16 @@ def _parse_filetype(fp): ".py4dstem", ".emd", ]: - return "H5" + if emd._is_EMD_file(fp): + return "emd" + + elif legacy.is_py4DSTEM_file(fp): + return "legacy" + + elif _is_arina(fp): + return "arina" + + elif fext in [ ".dm", ".dm3", @@ -33,5 +46,18 @@ def _parse_filetype(fp): else: raise Exception(f"Unrecognized file extension {fext}.") - +def _is_arina(filepath): + """ + Check if an h5 file is an Arina file. + """ + with h5py.File(filepath,'r') as f: + try: + assert("entry" in f.keys()) + except AssertionError: + return False + try: + assert("NX_class" in f["entry"].attrs.keys()) + except AssertionError: + return False + return True diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 3fe94ca41..82815779f 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -69,11 +69,11 @@ def read( assert(exists(filepath)), er2 filetype = _parse_filetype(filepath) - assert filetype == "H5", f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" + assert filetype in ('emd', 'legacy'), f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" # EMD 1.0 formatted files (py4DSTEM v0.14+) - if emd._is_EMD_file(filepath): + if filetype == "emd": version = emd._get_EMD_version(filepath) if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" @@ -88,7 +88,7 @@ def read( # legacy py4DSTEM files (v <= 0.13) else: - assert legacy.is_py4DSTEM_file(filepath), "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." + assert filetype == "legacy", "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." # read v13 From f846e921439af7429cae035347e06bf626a8c7d9 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 09:10:07 -0700 Subject: [PATCH 046/362] switched to svd-like orthogonalization (minor differences) --- .../iterative_mixedstate_ptychography.py | 22 ++++++++++++++++--- py4DSTEM/process/phase/utils.py | 14 ------------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 2d595fab1..067f2aa8a 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -24,7 +24,6 @@ ComplexProbe, fft_shift, generate_batches, - orthogonalize, polar_aliases, polar_symbols, ) @@ -1045,6 +1044,7 @@ def _probe_orthogonalization_constraint(self, current_probe): """ Ptychographic probe-orthogonalization constraint. Used to ensure mixed states are orthogonal to each other. + Adapted from https://github.com/AdvancedPhotonSource/tike/blob/main/src/tike/ptycho/probe.py#L690 Parameters -------- @@ -1057,9 +1057,25 @@ def _probe_orthogonalization_constraint(self, current_probe): Orthogonalized probe estimate """ xp = self._xp - shape = current_probe.shape + n_probes = self._num_probes - return orthogonalize(current_probe.reshape((shape[0], -1)), xp).reshape(shape) + # compute upper half of P* @ P + pairwise_dot_product = xp.empty((n_probes, n_probes), dtype=current_probe.dtype) + + for i in range(n_probes): + for j in range(i, n_probes): + pairwise_dot_product[i, j] = xp.sum( + current_probe[i].conj() * current_probe[j] + ) + + # compute eigenvectors (effectively cheaper way of computing V* from SVD) + _, evecs = xp.linalg.eigh(pairwise_dot_product, UPLO="U") + current_probe = xp.tensordot(evecs.T, current_probe, axes=1) + + # sort by real-space intensity + intensities = xp.sum(xp.abs(current_probe) ** 2, axis=(-2, -1)) + intensities_order = xp.argsort(intensities, axis=None)[::-1] + return current_probe[intensities_order] def _constraints( self, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 63377be75..c52076582 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -458,20 +458,6 @@ def spatial_frequencies(gpts: Tuple[int, int], sampling: Tuple[float, float]): ) -def projection(u: np.ndarray, v: np.ndarray, xp): - """Projection of vector u onto vector v.""" - return u * xp.vdot(u, v) / xp.vdot(u, u) - - -def orthogonalize(V: np.ndarray, xp): - """Non-normalized QR decomposition using repeated projections.""" - U = V.copy() - for i in range(1, V.shape[0]): - for j in range(i): - U[i, :] -= projection(U[j, :], V[i, :], xp) - return U - - ### FFT-shift functions From d7dbbafcf06044aa392dfbba4b289b834109b0d8 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 09:10:41 -0700 Subject: [PATCH 047/362] fixed mixed-state probe initialization bug, expanded preprocess viz to help debug --- .../iterative_mixedstate_ptychography.py | 59 +++++++++---------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 067f2aa8a..4b2187a15 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -442,16 +442,10 @@ def preprocess( # Randomly shift phase of other probes for i_probe in range(1, self._num_probes): shift_x = xp.exp( - -2j - * np.pi - * (xp.random.rand() - 0.5) - * ((xp.arange(sx) + 0.5) / sx - 0.5) + -2j * np.pi * (xp.random.rand() - 0.5) * xp.fft.fftfreq(sx) ) shift_y = xp.exp( - -2j - * np.pi - * (xp.random.rand() - 0.5) - * ((xp.arange(sy) + 0.5) / sy - 0.5) + -2j * np.pi * (xp.random.rand() - 0.5) * xp.fft.fftfreq(sy) ) self._probe[i_probe] = ( self._probe[i_probe - 1] * shift_x[:, None] * shift_y[None] @@ -487,7 +481,7 @@ def preprocess( self._object_fov_mask_inverse = np.invert(self._object_fov_mask) if plot_probe_overlaps: - figsize = kwargs.pop("figsize", (9, 4)) + figsize = kwargs.pop("figsize", (4.5 * self._num_probes + 4, 4)) cmap = kwargs.pop("cmap", "Greys_r") vmin = kwargs.pop("vmin", None) vmax = kwargs.pop("vmax", None) @@ -496,7 +490,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - self.probe_centered[0], + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -517,40 +511,41 @@ def preprocess( 0, ] - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize) + fig, axs = plt.subplots(1, self._num_probes + 1, figsize=figsize) - ax1.imshow( - complex_probe_rgb, - extent=probe_extent, - **kwargs, - ) - - divider = make_axes_locatable(ax1) - cax1 = divider.append_axes("right", size="5%", pad="2.5%") - add_colorbar_arg( - cax1, vmin=vmin, vmax=vmax, hue_start=hue_start, invert=invert - ) - ax1.set_ylabel("x [A]") - ax1.set_xlabel("y [A]") - ax1.set_title("Initial Probe[0]") + for i in range(self._num_probes): + axs[i].imshow( + complex_probe_rgb[i], + extent=probe_extent, + **kwargs, + ) + axs[i].set_ylabel("x [A]") + axs[i].set_xlabel("y [A]") + axs[i].set_title(f"Initial Probe[{i}]") + + divider = make_axes_locatable(axs[i]) + cax = divider.append_axes("right", size="5%", pad="2.5%") + add_colorbar_arg( + cax, vmin=vmin, vmax=vmax, hue_start=hue_start, invert=invert + ) - ax2.imshow( + axs[-1].imshow( asnumpy(probe_overlap), extent=extent, cmap=cmap, **kwargs, ) - ax2.scatter( + axs[-1].scatter( self.positions[:, 1], self.positions[:, 0], s=2.5, color=(1, 0, 0, 1), ) - ax2.set_ylabel("x [A]") - ax2.set_xlabel("y [A]") - ax2.set_xlim((extent[0], extent[1])) - ax2.set_ylim((extent[2], extent[3])) - ax2.set_title("Object Field of View") + axs[-1].set_ylabel("x [A]") + axs[-1].set_xlabel("y [A]") + axs[-1].set_xlim((extent[0], extent[1])) + axs[-1].set_ylim((extent[2], extent[3])) + axs[-1].set_title("Object Field of View") fig.tight_layout() From b4a93d315141c2a175dcc2a114ebd590ab114151 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 09:20:35 -0700 Subject: [PATCH 048/362] read abTEM --- py4DSTEM/io/filereaders/__init__.py | 1 + py4DSTEM/io/filereaders/read_abTEM.py | 59 +++++++++++++++++++++++++++ py4DSTEM/io/filereaders/read_arina.py | 20 ++++----- py4DSTEM/io/importfile.py | 8 +++- py4DSTEM/io/parsefiletype.py | 16 +++++++- 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 py4DSTEM/io/filereaders/read_abTEM.py diff --git a/py4DSTEM/io/filereaders/__init__.py b/py4DSTEM/io/filereaders/__init__.py index 44c083856..b6f4eb0a2 100644 --- a/py4DSTEM/io/filereaders/__init__.py +++ b/py4DSTEM/io/filereaders/__init__.py @@ -3,3 +3,4 @@ from py4DSTEM.io.filereaders.empad import read_empad from py4DSTEM.io.filereaders.read_mib import load_mib from py4DSTEM.io.filereaders.read_arina import read_arina +from py4DSTEM.io.filereaders.read_abTEM import read_abTEM diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py new file mode 100644 index 000000000..3e60f5fee --- /dev/null +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -0,0 +1,59 @@ +import h5py +from py4DSTEM.classes import DataCube + + +def read_abTEM( + filename, + mem="RAM", + binfactor: int = 1, +): + """ + File reader for abTEM 4D-STEM datasets + Args: + filename: str with path to master file + scan_width: x dimension of scan + mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is + loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" + leaves the data in storage and creates a memory map which points to + the diffraction patterns, allowing them to be retrieved individually + from storage. + binfactor (int): Diffraction space binning factor for bin-on-load. + + Returns: + DataCube + """ + assert mem == "RAM", "read_abTEM does not support memory mapping" + assert binfactor == 1, "abTEM files can only be read at full resolution" + + with h5py.File(filename, "r") as f: + datasets = {} + for key in f.keys(): + datasets[key] = f.get(key)[()] + + data = datasets["array"] + assert len(data.shape) == 4, "reader is for 4D-STEM datasets only" + + datacube = DataCube(data=data) + + sampling = datasets["sampling"] + units = datasets["units"] + + datacube.calibration.set_R_pixel_size(sampling[0]) + if sampling[0] != sampling[1]: + print( + "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" + ) + datacube.calibration.set_Q_pixel_size(sampling[2]) + if sampling[2] != sampling[3]: + print( + "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with qx calibration" + ) + + if units[0] == b"\xc3\x85": + datacube.calibration.set_R_pixel_units("A") + else: + datacube.calibration.set_R_pixel_units(units[0].decode("utf-8")) + + datacube.calibration.set_Q_pixel_units(units[2].decode("utf-8")) + + return datacube diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 4d0b605fd..0f334f52b 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -9,8 +9,8 @@ def read_arina( filename, scan_width, mem="RAM", - binfactor:int=1, - dtype_bin:float=None, + binfactor: int = 1, + dtype_bin: float = None, ): """ @@ -24,13 +24,13 @@ def read_arina( the diffraction patterns, allowing them to be retrieved individually from storage. binfactor (int): Diffraction space binning factor for bin-on-load. - dtype_bin(float): specify datatype for bin on load if need something + dtype_bin(float): specify datatype for bin on load if need something other than uint16 Returns: DataCube """ - assert mem == "RAM", "ARNIA does not support memory mapping" + assert mem == "RAM", "read_arina does not support memory mapping" f = h5py.File(filename, "r") nimages = 0 @@ -41,10 +41,10 @@ def read_arina( height = f["entry"]["data"][dset].shape[1] width = f["entry"]["data"][dset].shape[2] dtype = f["entry"]["data"][dset].dtype - - width = width//binfactor - height = height//binfactor - + + width = width // binfactor + height = height // binfactor + assert ( nimages % scan_width < 1e-6 ), "scan_width must be integer multiple of x*y size" @@ -86,8 +86,8 @@ def _processDataSet(dset, start_index, array_3D, binfactor): for i in range(nimages_dset): if binfactor == 1: array_3D[image_index] = dset[i].astype(array_3D.dtype) - else: + else: array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) - + image_index = image_index + 1 return image_index diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 9048e0f7f..9c3287642 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -10,7 +10,8 @@ read_dm, read_gatan_K2_bin, load_mib, - read_arina + read_arina, + read_abTEM ) @@ -36,7 +37,7 @@ def import_file( from storage. binfactor (int): Diffraction space binning factor for bin-on-load. filetype (str): Used to override automatic filetype detection. - options include "dm", "empad", "gatan_K2_bin", "mib","arina" + options include "dm", "empad", "gatan_K2_bin", "mib", "arina", "abTEM" **kwargs: any additional kwargs are passed to the downstream reader - refer to the individual filetype reader function call signatures and docstrings for more details. @@ -74,6 +75,7 @@ def import_file( "gatan_K2_bin", "mib", "arina", + "abTEM" # "kitware_counted", ], "Error: filetype not recognized" @@ -89,6 +91,8 @@ def import_file( data = load_mib(filepath, mem=mem, binfactor=binfactor, **kwargs) elif filetype == "arina": data = read_arina(filepath, mem=mem, binfactor=binfactor, **kwargs) + elif filetype == "abTEM": + data = read_abTEM(filepath, mem=mem, binfactor=binfactor, **kwargs) else: raise Exception("Bad filetype!") diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index b2889511a..ab7529ec6 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -26,7 +26,9 @@ def _parse_filetype(fp): elif _is_arina(fp): return "arina" - + elif _is_abTEM(fp): + return "abTEM" + elif fext in [ ".dm", ".dm3", @@ -61,3 +63,15 @@ def _is_arina(filepath): return False return True +def _is_abTEM(filepath): + """ + Check if an h5 file is an abTEM file. + """ + with h5py.File(filepath,'r') as f: + try: + assert("array" in f.keys()) + except AssertionError: + return False + return True + + From b81e74f903dcd18d9d6a0b0c0e250b68816ac4bd Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 09:45:46 -0700 Subject: [PATCH 049/362] fix warning statement and doc strings --- py4DSTEM/io/filereaders/read_abTEM.py | 3 +-- py4DSTEM/io/importfile.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index 3e60f5fee..1008bcc0e 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -10,8 +10,7 @@ def read_abTEM( """ File reader for abTEM 4D-STEM datasets Args: - filename: str with path to master file - scan_width: x dimension of scan + filename: str with path to file mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" leaves the data in storage and creates a memory map which points to diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 9c3287642..98ef05238 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -67,8 +67,8 @@ def import_file( filetype = _parse_filetype(filepath) if filetype is None else filetype - if filetype == 'EMD': - raise Exception("EMD file detected - use py4DSTEM.read, not py4DSTEM.import_file!") + if filetype in ('emd', 'legacy'): + raise Exception("EMD file or py4DSTEM detected - use py4DSTEM.read, not py4DSTEM.import_file!") assert filetype in [ "dm", "empad", From 5565d957cba2f698d8f5d3e29eb86224c69ff953 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 10:16:28 -0700 Subject: [PATCH 050/362] fixed read-write of corner-centered probes --- .../process/phase/iterative_base_class.py | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index e17b677a1..34f1a221f 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -1166,6 +1166,15 @@ def to_h5(self, group): data=self._polar_parameters, ) + # object + self._object_emd = Array( + name="reconstruction_object", + data=asnumpy(self._xp.asarray(self._object)), + ) + + # probe + self._probe_emd = Array(name="reconstruction_probe", data=asnumpy(self._probe)) + if is_stack: iterations_labels = [f"iteration_{i:03}" for i in iterations] @@ -1173,32 +1182,20 @@ def to_h5(self, group): object_iterations = [ np.asarray(self.object_iterations[i]) for i in iterations ] - self._object_emd = Array( - name="reconstruction_object", + self._object_iterations_emd = Array( + name="reconstruction_object_iterations", data=np.stack(object_iterations, axis=0), slicelabels=iterations_labels, ) # probe probe_iterations = [self.probe_iterations[i] for i in iterations] - self._probe_emd = Array( - name="reconstruction_probe", + self._probe_iterations_emd = Array( + name="reconstruction_probe_iterations", data=np.stack(probe_iterations, axis=0), slicelabels=iterations_labels, ) - else: - # object - self._object_emd = Array( - name="reconstruction_object", - data=asnumpy(self._xp.asarray(self._object)), - ) - - # probe - self._probe_emd = Array( - name="reconstruction_probe", data=asnumpy(self._probe) - ) - # exit_waves if self._save_exit_waves: self._exit_waves_emd = Array( @@ -1239,13 +1236,8 @@ def _get_constructor_args(cls, group): else: dc = None - # Check if stack - if dict_data["_object_emd"].is_stack: - obj = dict_data["_object_emd"][-1].data - probe = dict_data["_probe_emd"][-1].data - else: - obj = dict_data["_object_emd"].data - probe = dict_data["_probe_emd"].data + obj = dict_data["_object_emd"].data + probe = dict_data["_probe_emd"].data # Populate args and return kwargs = { @@ -1303,8 +1295,8 @@ def _populate_instance(self, group): # Check if stack if hasattr(error, "__len__"): - self.object_iterations = list(dict_data["_object_emd"].data) - self.probe_iterations = list(dict_data["_probe_emd"].data) + self.object_iterations = list(dict_data["_object_iterations_emd"].data) + self.probe_iterations = list(dict_data["_probe_iterations_emd"].data) self.error_iterations = error self.error = error[-1] else: @@ -1313,7 +1305,7 @@ def _populate_instance(self, group): # Slim preprocessing to enable visualize self._positions_px_com = xp.mean(self._positions_px, axis=0) self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self._preprocessed = True def _set_polar_parameters(self, parameters: dict): @@ -1401,9 +1393,9 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): self._object_padding_px = (float_padding, float_padding) elif np.isscalar(self._object_padding_px[0]): self._object_padding_px = ( - (self._object_padding_px[0],)*2, - (self._object_padding_px[1],)*2 - ) + (self._object_padding_px[0],) * 2, + (self._object_padding_px[1],) * 2, + ) positions[:, 0] += self._object_padding_px[0][0] positions[:, 1] += self._object_padding_px[1][0] From 1a8fcbef906eec659c46cf2d18ef01e4a70e2466 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 20 Jun 2023 12:50:37 -0400 Subject: [PATCH 051/362] fixes gdrive downloader, adds test data downloader command line interface --- py4DSTEM/io/__init__.py | 12 +- py4DSTEM/io/google_drive_downloader.py | 205 +++++-------- py4DSTEM/io/sample_file_ids.py | 89 ++++++ test/gettestdata.py | 71 +++++ test/unit_test_data/crystal/LCO.cif | 96 ------ test/unit_test_data/crystal/Li2MnO3.cif | 79 ----- test/unit_test_data/crystal/LiMn2O4.cif | 277 ------------------ .../unit_test_data/crystal/braggdisks_cali.h5 | Bin 3099136 -> 0 bytes 8 files changed, 237 insertions(+), 592 deletions(-) create mode 100644 py4DSTEM/io/sample_file_ids.py create mode 100644 test/gettestdata.py delete mode 100644 test/unit_test_data/crystal/LCO.cif delete mode 100644 test/unit_test_data/crystal/Li2MnO3.cif delete mode 100644 test/unit_test_data/crystal/LiMn2O4.cif delete mode 100644 test/unit_test_data/crystal/braggdisks_cali.h5 diff --git a/py4DSTEM/io/__init__.py b/py4DSTEM/io/__init__.py index 399127577..71a0f2dd5 100644 --- a/py4DSTEM/io/__init__.py +++ b/py4DSTEM/io/__init__.py @@ -5,15 +5,9 @@ from py4DSTEM.io.save import save -# TODO -# - read fn - triage new/old EMD files -# - save fn - call EMD write fn with any special defaults -# (mod root __init__ emd.write import) - # google downloader -from py4DSTEM.io.google_drive_downloader import ( - download_file_from_google_drive, - get_sample_data_ids -) +from py4DSTEM.io.google_drive_downloader import gdrive_download +from py4DSTEM.io.sample_file_ids import get_sample_file_ids + diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index 052dbdace..a4ff72abe 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -1,148 +1,91 @@ import gdown -from typing import Union -import pathlib import os +from py4DSTEM.io.sample_file_ids import file_ids, collection_ids -# Built-in sample datasets - -# single files -sample_file_ids = { - 'FCU-Net' : '1-KX0saEYfhZ9IJAOwabH38PCVtfXidJi', - 'sample_diffraction_pattern':'1ymYMnuDC0KV6dqduxe2O1qafgSd0jjnU', - 'Au_sim':'1PmbCYosA1eYydWmmZebvf6uon9k_5g_S', - 'carbon_nanotube':'1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM', - 'Si_SiGe_exp':'1fXNYSGpe6w6E9RBA-Ai_owZwoj3w8PNC', - 'Si_SiGe_probe':'141Tv0YF7c5a-MCrh3CkY_w4FgWtBih80', - 'Si_SiGe_EELS_strain':'1klkecq8IuEOYB-bXchO7RqOcgCl4bmDJ', - 'AuAgPd_wire':'1OQYW0H6VELsmnLTcwicP88vo2V5E3Oyt', - 'AuAgPd_wire_probe':'17OduUKpxVBDumSK_VHtnc2XKkaFVN8kq', - 'polycrystal_2D_WS2':'1AWB3-UTPiTR9dgrEkNFD7EJYsKnbEy0y', - 'WS2cif':'13zBl6aFExtsz_sew-L0-_ALYJfcgHKjo', - 'polymers':'1lK-TAMXN1MpWG0Q3_4vss_uEZgW2_Xh7', - 'vac_probe':'1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', -} - -# collections of files -sample_collection_ids = { - 'unit_test_data' : ( - ('dm_test_file.dm3', '1RxI1QY6vYMDqqMVPt5GBN6Q_iCwHFU4B'), - ), - 'tutorials' : ( - ('simulated_Au_single+polyXtal.h5', sample_file_ids['Au_sim']), - ('carbon_nanotube.h5', sample_file_ids['carbon_nanotube']), - ('Si_SiGe_exp.h5',sample_file_ids['Si_SiGe_exp']), - ('Si_SiGe_probe.h5',sample_file_ids['Si_SiGe_probe']), - ('Si_SiGe_EELS_strain.h5',sample_file_ids['Si_SiGe_EELS_strain']), - ('AuAgPd_wire.h5',sample_file_ids['AuAgPd_wire']), - ('AuAgPd_wire_probe.h5',sample_file_ids['AuAgPd_wire_probe']), - ('polycrystal_2D_WS2.h5',sample_file_ids['polycrystal_2D_WS2']), - ('WS2.cif',sample_file_ids['WS2cif']), - ('polymers.h5',sample_file_ids['polymers']), - ('vac_probe.h5',sample_file_ids['vac_probe']), - ), -} - - -def download_file_from_google_drive(id_, destination, overwrite=False): +def gdrive_download( + id_, + destination = None, + overwrite = False, + filename = None, + verbose = True, + ): """ - Downloads a file or collection of files from google drive to the - destination file path. - - Args: - id_ (str): File ID for the desired file. May be: - - the file id, i.e. for - https://drive.google.com/file/d/1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM/ - id='1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM' - - the complete URL, - - a special string denoting a sample dataset or collection of - datasets. For a list of sample datasets and their keys, run - get_sample_data_ids(). - destination (str or Path): path file will be downloaded to. For - collections of files, this should point to an existing directory; - a subdirectory will be created inside this directory whose name - will be given by `id_`, and the colletion of files will be placed - inside that subdirectory. If a subdirectory of this name already - exists, aborts or deletes and overwrite the entire subdirectory, - depending on the value of `overwrite`. - overwrite (bool): turn overwrite protection on/off + Downloads a file or collection of files from google drive. + + Parameters + ---------- + id_ : str + File ID for the desired file. May be either a key from the list + of files and collections of files accessible at get_sample_file_ids(), + or a complete url, or the portions of a google drive link specifying + the file ID, i.e. for the address + https://drive.google.com/file/d/1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM/, + the id string '1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM'. + destination : None or str + The location to download to. If None, downloads to the current + working directory. If a string is passed which points to a valid + location on the filesystem, downloads there. For collections of + files, makes a new directory named after the collection id and + places all files there. + overwrite : bool + Turns overwrite protection on/off. + filename : None or str + Used only if `id_` is a url or gdrive id. Specifies the name of the + output file. If left as None, saves to 'gdrivedownload.file'. If `id_` + is a key from the sample file id list, this parameter is ignored and + the filenames in that list are used. + verbose : bool + Toggles verbose output """ - # handle paths - - # for collections of files - if id_ in sample_collection_ids.keys(): + # parse destination + if destination is None: + destination = os.getcwd() + assert(os.path.exists(destination)), f"`destination` must exist on filesystem. Received {destination}" + + # download single files + if id_ not in collection_ids: + + # assign the name and id + kwargs = { + 'fuzzy' : True + } + if id_ in file_ids: + f = file_ids[id_] + filename = f[0] + kwargs['id'] = f[1] + else: + filename = 'gdrivedownload.file' if filename is None else filename + kwargs['url'] = id_ + + # download + kwargs['output'] = os.path.join(destination, filename) + if not(overwrite) and os.path.exists(kwargs['output']): + if verbose: + print(f"A file already exists at {kwargs['output']}, skipping...") + else: + gdown.download( **kwargs ) - # check if directory exists - assert os.path.exists(destination), "specified directory does not exist; check filepath" + # download a collections of files + else: - # update the path with a new sub-directory name + # set destination destination = os.path.join(destination, id_) - - # check if it already exists - if os.path.exists(destination): - - # check if it contains any files - paths = os.listdir(destination) - if len(paths) > 0: - - # check `overwrite` - if overwrite: - for p in paths: - os.remove(os.path.join(destination, p)) - else: - raise Exception('a populated directory exists at the specified location. to overwrite set `overwrite=True`.') - - # if it doesn't exist, make a new directory - else: + if not os.path.exists(destination): os.mkdir(destination) - # get the files - for file_name,file_id in sample_collection_ids[id_]: - if file_id[:4].lower() == 'http': - gdown.download( - url = file_id, - output = os.path.join(destination, file_name), - fuzzy = True - ) + # loop + for x in collection_ids[id_]: + file_name,file_id = file_ids[x] + output = os.path.join(destination, file_name) + # download + if not(overwrite) and os.path.exists(output): + if verbose: + print(f"A file already exists at {output}, skipping...") else: gdown.download( id = file_id, - output = os.path.join(destination, file_name), + output = output, fuzzy = True ) - return None - - - # for single files - - # Check and handle if a file at the destination filepath exists - if os.path.exists(destination): - - # check `overwrite` - if overwrite == True: - print(f"File already existed, downloading and overwriting") - os.remove(destination) - else: - raise Exception('File already exists; aborting. To overwrite, use `overwrite=True`.') - - # Check if the id_ is a key pointing to a known sample dataset - if id_ in sample_file_ids.keys(): - id_ = sample_file_ids[id_] - - # Check if `id_` is a file ID or a URL, and download - if id_[:4].lower()=='http': - gdown.download(url=id_,output=destination,fuzzy=True) - else: - gdown.download(id=id_,output=destination,fuzzy=True) - - return None - - - -def get_sample_data_ids(): - return {'files' : sample_file_ids.keys(), - 'collections' : sample_collection_ids.keys()} - - - diff --git a/py4DSTEM/io/sample_file_ids.py b/py4DSTEM/io/sample_file_ids.py new file mode 100644 index 000000000..b42b7eccc --- /dev/null +++ b/py4DSTEM/io/sample_file_ids.py @@ -0,0 +1,89 @@ +# single files +file_ids = { + 'sample_diffraction_pattern' : ( + 'a_diffraction_pattern.h5', + '1ymYMnuDC0KV6dqduxe2O1qafgSd0jjnU', + ), + 'Au_sim' : ( + 'au_sim.h5', + '1PmbCYosA1eYydWmmZebvf6uon9k_5g_S', + ), + 'carbon_nanotube' : ( + 'carbon_nanotube.h5', + '1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM', + ), + 'Si_SiGe_exp' : ( + 'Si_SiGe_exp.h5', + '1fXNYSGpe6w6E9RBA-Ai_owZwoj3w8PNC', + ), + 'Si_SiGe_probe' : ( + 'Si_SiGe_probe.h5', + '141Tv0YF7c5a-MCrh3CkY_w4FgWtBih80', + ), + 'Si_SiGe_EELS_strain' : ( + 'Si_SiGe_EELS_strain.h5', + '1klkecq8IuEOYB-bXchO7RqOcgCl4bmDJ', + ), + 'AuAgPd_wire' : ( + 'AuAgPd_wire.h5', + '1OQYW0H6VELsmnLTcwicP88vo2V5E3Oyt', + ), + 'AuAgPd_wire_probe' : ( + 'AuAgPd_wire_probe.h5', + '17OduUKpxVBDumSK_VHtnc2XKkaFVN8kq', + ), + 'polycrystal_2D_WS2' : ( + 'polycrystal_2D_WS2.h5', + '1AWB3-UTPiTR9dgrEkNFD7EJYsKnbEy0y', + ), + 'WS2cif' : ( + 'WS2.cif', + '13zBl6aFExtsz_sew-L0-_ALYJfcgHKjo', + ), + 'polymers' : ( + 'polymers.h5', + '1lK-TAMXN1MpWG0Q3_4vss_uEZgW2_Xh7', + ), + 'vac_probe' : ( + 'vac_probe.h5', + '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', + ), + 'small_dm3' : ( + 'small_dm3.dm3', + '1RxI1QY6vYMDqqMVPt5GBN6Q_iCwHFU4B' + ), + 'FCU-Net' : ( + 'filename.name', + '1-KX0saEYfhZ9IJAOwabH38PCVtfXidJi', + ), +} + +# collections of files +collection_ids = { + 'tutorials' : ( + 'Au_sim', + 'carbon_nanotube', + 'Si_SiGe_exp', + 'Si_SiGe_probe', + 'Si_SiGe_EELS_strain', + 'AuAgPd_wire', + 'AuAgPd_wire_probe', + 'polycrystal_2D_WS2', + 'WS2cif', + 'polymers', + 'vac_probe', + ), + 'io_test_data' : ( + 'small_dm3', + 'vac_probe', + ), +} + + +def get_sample_file_ids(): + return { + 'files' : file_ids.keys(), + 'collections' : collection_ids.keys() + } + + diff --git a/test/gettestdata.py b/test/gettestdata.py new file mode 100644 index 000000000..eb5e7c5a8 --- /dev/null +++ b/test/gettestdata.py @@ -0,0 +1,71 @@ +# A command line tool for downloading data to run the py4DSTEM test suite + + +import argparse +from os.path import join, exists +from os import makedirs + +from py4DSTEM import _TESTPATH as testpath +from py4DSTEM.io import gdrive_download as download + + + +# Make the argument parser +parser = argparse.ArgumentParser( + description = "A command line tool for downloading data to run the py4DSTEM test suite" +) + +# Set up data download options +data_options = [ + 'tutorials', + 'io', +] + +# Add arguments +parser.add_argument( + "data", + help = "which data to download.", + choices = data_options, +) +parser.add_argument( + "-o", "--overwrite", + help = "if turned on, overwrite files that are already present. Otherwise, skips these files.", + action = "store_true" +) +parser.add_argument( + "-v", "--verbose", + help = "turn on verbose output", + action = "store_true" +) + + + +# Get the command line arguments +args = parser.parse_args() + + +# Set up paths +if not exists(testpath): + makedirs(testpath) + + +# Set data collection key +if args.data == 'tutorials': + data = 'tutorials' +elif args.data == 'io': + data = 'io_test_data' +else: + raise Exception(f"invalid data choice, {parser.data}") + +# Download data +download( + data, + destination = testpath, + overwrite = args.overwrite, + verbose = args.verbose +) + + + + + diff --git a/test/unit_test_data/crystal/LCO.cif b/test/unit_test_data/crystal/LCO.cif deleted file mode 100644 index 8fe2b777e..000000000 --- a/test/unit_test_data/crystal/LCO.cif +++ /dev/null @@ -1,96 +0,0 @@ -#------------------------------------------------------------------------------ -#$Date: 2016-02-13 21:28:24 +0200 (Sat, 13 Feb 2016) $ -#$Revision: 176429 $ -#$URL: svn://www.crystallography.net/cod/cif/1/53/38/1533825.cif $ -#------------------------------------------------------------------------------ -# -# This file is available in the Crystallography Open Database (COD), -# http://www.crystallography.net/ -# -# All data on this site have been placed in the public domain by the -# contributors. -# -data_1533825 -loop_ -_publ_author_name -'Hong Jin K' -'Oh Seung M' -_publ_section_title -; - Crystal structure and electrochemical performance of Li Ni1-x Cox O2 (0 - <= x < 1.0) according to Co substitution -; -_journal_name_full -'Journal of the Korean Electrochemical Society' -_journal_page_first 1 -_journal_page_last 5 -_journal_volume 6 -_journal_year 2003 -_chemical_formula_sum 'Co Li O2' -_chemical_name_systematic 'Li (Co O2)' -_space_group_IT_number 166 -_symmetry_space_group_name_Hall '-R 3 2"' -_symmetry_space_group_name_H-M 'R -3 m :H' -_cell_angle_alpha 90 -_cell_angle_beta 90 -_cell_angle_gamma 120 -_cell_formula_units_Z 3 -_cell_length_a 2.92 -_cell_length_b 2.92 -_cell_length_c 14.25 -_cell_volume 96.337 -_citation_journal_id_ASTM JKESFC -_cod_data_source_file HongJinK_JKESFC_2003_777.cif -_cod_data_source_block Co1Li1O2 -_cod_original_cell_volume 96.33704 -_cod_original_formula_sum 'Co1 Li1 O2' -_cod_database_code 1533825 -loop_ -_symmetry_equiv_pos_as_xyz -x,y,z --y,x-y,z --x+y,-x,z -y,x,-z --x,-x+y,-z -x-y,-y,-z --x,-y,-z -y,-x+y,-z -x-y,x,-z --y,-x,z -x,x-y,z --x+y,y,z -x+2/3,y+1/3,z+1/3 --y+2/3,x-y+1/3,z+1/3 --x+y+2/3,-x+1/3,z+1/3 -y+2/3,x+1/3,-z+1/3 --x+2/3,-x+y+1/3,-z+1/3 -x-y+2/3,-y+1/3,-z+1/3 --x+2/3,-y+1/3,-z+1/3 -y+2/3,-x+y+1/3,-z+1/3 -x-y+2/3,x+1/3,-z+1/3 --y+2/3,-x+1/3,z+1/3 -x+2/3,x-y+1/3,z+1/3 --x+y+2/3,y+1/3,z+1/3 -x+1/3,y+2/3,z+2/3 --y+1/3,x-y+2/3,z+2/3 --x+y+1/3,-x+2/3,z+2/3 -y+1/3,x+2/3,-z+2/3 --x+1/3,-x+y+2/3,-z+2/3 -x-y+1/3,-y+2/3,-z+2/3 --x+1/3,-y+2/3,-z+2/3 -y+1/3,-x+y+2/3,-z+2/3 -x-y+1/3,x+2/3,-z+2/3 --y+1/3,-x+2/3,z+2/3 -x+1/3,x-y+2/3,z+2/3 --x+y+1/3,y+2/3,z+2/3 -loop_ -_atom_site_label -_atom_site_type_symbol -_atom_site_fract_x -_atom_site_fract_y -_atom_site_fract_z -_atom_site_occupancy -_atom_site_U_iso_or_equiv -O1 O-2 0 0 0.2268 1 0.0 -Co1 Co+3 0 0 0 1 0.0 -Li1 Li+1 0 0 0.5 1 0.0 diff --git a/test/unit_test_data/crystal/Li2MnO3.cif b/test/unit_test_data/crystal/Li2MnO3.cif deleted file mode 100644 index 7a74b4fae..000000000 --- a/test/unit_test_data/crystal/Li2MnO3.cif +++ /dev/null @@ -1,79 +0,0 @@ -#------------------------------------------------------------------------------ -#$Date: 2015-01-27 21:58:39 +0200 (Tue, 27 Jan 2015) $ -#$Revision: 130149 $ -#$URL: svn://www.crystallography.net/cod/cif/1/00/83/1008373.cif $ -#------------------------------------------------------------------------------ -# -# This file is available in the Crystallography Open Database (COD), -# http://www.crystallography.net/ -# -# All data on this site have been placed in the public domain by the -# contributors. -# -data_1008373 -loop_ -_publ_author_name -'Strobel, P' -'Lambert-Andron, B' -_publ_section_title -; -Crystallographic and Magnetic Structure of Li~2~ Mn O~3~ -; -_journal_coden_ASTM JSSCBI -_journal_name_full 'Journal of Solid State Chemistry' -_journal_page_first 90 -_journal_page_last 98 -_journal_paper_doi 10.1016/0022-4596(88)90305-2 -_journal_volume 75 -_journal_year 1988 -_chemical_formula_structural 'Li2 Mn O3' -_chemical_formula_sum 'Li2 Mn O3' -_chemical_name_systematic 'Dilithium manganese(IV) trioxide' -_space_group_IT_number 12 -_symmetry_cell_setting monoclinic -_symmetry_Int_Tables_number 12 -_symmetry_space_group_name_Hall '-C 2y' -_symmetry_space_group_name_H-M 'C 1 2/m 1' -_cell_angle_alpha 90 -_cell_angle_beta 109.46(3) -_cell_angle_gamma 90 -_cell_formula_units_Z 4 -_cell_length_a 5.1 -_cell_length_b 8.5 -_cell_length_c 5.1 -_cell_volume 199.8 -_refine_ls_R_factor_all 0.02 -_cod_database_code 1008373 -loop_ -_symmetry_equiv_pos_as_xyz -x,y,z -x,-y,z --x,-y,-z --x,y,-z -1/2+x,1/2+y,z -1/2+x,1/2-y,z -1/2-x,1/2-y,-z -1/2-x,1/2+y,-z -loop_ -_atom_site_label -_atom_site_type_symbol -_atom_site_symmetry_multiplicity -_atom_site_Wyckoff_symbol -_atom_site_fract_x -_atom_site_fract_y -_atom_site_fract_z -_atom_site_occupancy -_atom_site_attached_hydrogens -_atom_site_calc_flag -Mn1 Mn4+ 4 g 0. 0.16708(2) 0. 1. 0 d -Li1 Li1+ 2 b 0. 0.5 0. 1. 0 d -Li2 Li1+ 2 c 0. 0. 0.5 1. 0 d -Li3 Li1+ 4 h 0. 0.6606(3) 0.5 1. 0 d -O1 O2- 4 i 0.2189(2) 0. 0.2273(2) 1. 0 d -O2 O2- 8 j 0.2540(1) 0.32119(7) 0.2233(1) 1. 0 d -loop_ -_atom_type_symbol -_atom_type_oxidation_number -Mn4+ 4.000 -Li1+ 1.000 -O2- -2.000 diff --git a/test/unit_test_data/crystal/LiMn2O4.cif b/test/unit_test_data/crystal/LiMn2O4.cif deleted file mode 100644 index 81f8db377..000000000 --- a/test/unit_test_data/crystal/LiMn2O4.cif +++ /dev/null @@ -1,277 +0,0 @@ -#------------------------------------------------------------------------------ -#$Date: 2016-02-20 20:10:49 +0200 (Sat, 20 Feb 2016) $ -#$Revision: 176788 $ -#$URL: svn://www.crystallography.net/cod/cif/1/51/39/1513962.cif $ -#------------------------------------------------------------------------------ -# -# This file is available in the Crystallography Open Database (COD), -# http://www.crystallography.net/ -# -# All data on this site have been placed in the public domain by the -# contributors. -# -data_1513962 -loop_ -_publ_author_name -'Mosbah, A.' -'Verbaere, A.' -'Tournoux, M.' -_publ_section_title -; - Phases Lix Mn O2 lambda rattachees au type spinelle -; -_journal_coden_ASTM MRBUAC -_journal_name_full 'Materials Research Bulletin' -_journal_page_first 1375 -_journal_page_last 1381 -_journal_year 1983 -_chemical_formula_structural 'Li Mn2 O4' -_chemical_formula_sum 'Li Mn2 O4' -_chemical_name_systematic 'Lithium Dimanganese Tetraoxide' -_space_group_IT_number 227 -_symmetry_Int_Tables_number 227 -_symmetry_space_group_name_Hall '-F 4vw 2vw 3' -_symmetry_space_group_name_H-M 'F d -3 m :2' -_audit_creation_date 1999-11-30 -_audit_update_record 2005-10-01 -_cell_angle_alpha 90. -_cell_angle_beta 90. -_cell_angle_gamma 90. -_cell_formula_units_Z 8 -_cell_length_a 8.245(1) -_cell_length_b 8.245(1) -_cell_length_c 8.245(1) -_cell_volume 560.50(12) -_refine_ls_R_factor_all 0.036 -_cod_data_source_file 'data_LiMn2O4melanie040485.cif' -_cod_data_source_block -/var/www/cod/tmp/uploads/1395678109.95-D290F29E9218B844.cif -_cod_original_cell_volume 560.5 -_cod_original_sg_symbol_H-M 'F d -3 m Z' -_cod_original_formula_sum 'Li1 Mn2 O4' -_cod_database_code 1513962 -loop_ -_symmetry_equiv_pos_site_id -_symmetry_equiv_pos_as_xyz -1 '-z, y+3/4, x+3/4' -2 'z+3/4, -y, x+3/4' -3 'z+3/4, y+3/4, -x' -4 '-z, -y, -x' -5 'y+3/4, x+3/4, -z' -6 '-y, x+3/4, z+3/4' -7 'y+3/4, -x, z+3/4' -8 '-y, -x, -z' -9 'x+3/4, -z, y+3/4' -10 'x+3/4, z+3/4, -y' -11 '-x, z+3/4, y+3/4' -12 '-x, -z, -y' -13 '-z, x+3/4, y+3/4' -14 'z+3/4, x+3/4, -y' -15 'z+3/4, -x, y+3/4' -16 '-z, -x, -y' -17 'y+3/4, -z, x+3/4' -18 '-y, z+3/4, x+3/4' -19 'y+3/4, z+3/4, -x' -20 '-y, -z, -x' -21 'x+3/4, y+3/4, -z' -22 'x+3/4, -y, z+3/4' -23 '-x, y+3/4, z+3/4' -24 '-x, -y, -z' -25 'z, -y+1/4, -x+1/4' -26 '-z+1/4, y, -x+1/4' -27 '-z+1/4, -y+1/4, x' -28 'z, y, x' -29 '-y+1/4, -x+1/4, z' -30 'y, -x+1/4, -z+1/4' -31 '-y+1/4, x, -z+1/4' -32 'y, x, z' -33 '-x+1/4, z, -y+1/4' -34 '-x+1/4, -z+1/4, y' -35 'x, -z+1/4, -y+1/4' -36 'x, z, y' -37 'z, -x+1/4, -y+1/4' -38 '-z+1/4, -x+1/4, y' -39 '-z+1/4, x, -y+1/4' -40 'z, x, y' -41 '-y+1/4, z, -x+1/4' -42 'y, -z+1/4, -x+1/4' -43 '-y+1/4, -z+1/4, x' -44 'y, z, x' -45 '-x+1/4, -y+1/4, z' -46 '-x+1/4, y, -z+1/4' -47 'x, -y+1/4, -z+1/4' -48 'x, y, z' -49 '-z, y+1/4, x+1/4' -50 '-z+1/2, y+3/4, x+1/4' -51 '-z+1/2, y+1/4, x+3/4' -52 'z+3/4, -y+1/2, x+1/4' -53 'z+1/4, -y, x+1/4' -54 'z+1/4, -y+1/2, x+3/4' -55 'z+3/4, y+1/4, -x+1/2' -56 'z+1/4, y+3/4, -x+1/2' -57 'z+1/4, y+1/4, -x' -58 '-z, -y+1/2, -x+1/2' -59 '-z+1/2, -y, -x+1/2' -60 '-z+1/2, -y+1/2, -x' -61 'y+3/4, x+1/4, -z+1/2' -62 'y+1/4, x+3/4, -z+1/2' -63 'y+1/4, x+1/4, -z' -64 '-y, x+1/4, z+1/4' -65 '-y+1/2, x+3/4, z+1/4' -66 '-y+1/2, x+1/4, z+3/4' -67 'y+3/4, -x+1/2, z+1/4' -68 'y+1/4, -x, z+1/4' -69 'y+1/4, -x+1/2, z+3/4' -70 '-y, -x+1/2, -z+1/2' -71 '-y+1/2, -x, -z+1/2' -72 '-y+1/2, -x+1/2, -z' -73 'x+3/4, -z+1/2, y+1/4' -74 'x+1/4, -z, y+1/4' -75 'x+1/4, -z+1/2, y+3/4' -76 'x+3/4, z+1/4, -y+1/2' -77 'x+1/4, z+3/4, -y+1/2' -78 'x+1/4, z+1/4, -y' -79 '-x, z+1/4, y+1/4' -80 '-x+1/2, z+3/4, y+1/4' -81 '-x+1/2, z+1/4, y+3/4' -82 '-x, -z+1/2, -y+1/2' -83 '-x+1/2, -z, -y+1/2' -84 '-x+1/2, -z+1/2, -y' -85 '-z, x+1/4, y+1/4' -86 '-z+1/2, x+3/4, y+1/4' -87 '-z+1/2, x+1/4, y+3/4' -88 'z+3/4, x+1/4, -y+1/2' -89 'z+1/4, x+3/4, -y+1/2' -90 'z+1/4, x+1/4, -y' -91 'z+3/4, -x+1/2, y+1/4' -92 'z+1/4, -x, y+1/4' -93 'z+1/4, -x+1/2, y+3/4' -94 '-z, -x+1/2, -y+1/2' -95 '-z+1/2, -x, -y+1/2' -96 '-z+1/2, -x+1/2, -y' -97 'y+3/4, -z+1/2, x+1/4' -98 'y+1/4, -z, x+1/4' -99 'y+1/4, -z+1/2, x+3/4' -100 '-y, z+1/4, x+1/4' -101 '-y+1/2, z+3/4, x+1/4' -102 '-y+1/2, z+1/4, x+3/4' -103 'y+3/4, z+1/4, -x+1/2' -104 'y+1/4, z+3/4, -x+1/2' -105 'y+1/4, z+1/4, -x' -106 '-y, -z+1/2, -x+1/2' -107 '-y+1/2, -z, -x+1/2' -108 '-y+1/2, -z+1/2, -x' -109 'x+3/4, y+1/4, -z+1/2' -110 'x+1/4, y+3/4, -z+1/2' -111 'x+1/4, y+1/4, -z' -112 'x+3/4, -y+1/2, z+1/4' -113 'x+1/4, -y, z+1/4' -114 'x+1/4, -y+1/2, z+3/4' -115 '-x, y+1/4, z+1/4' -116 '-x+1/2, y+3/4, z+1/4' -117 '-x+1/2, y+1/4, z+3/4' -118 '-x, -y+1/2, -z+1/2' -119 '-x+1/2, -y, -z+1/2' -120 '-x+1/2, -y+1/2, -z' -121 'z, -y+3/4, -x+3/4' -122 'z+1/2, -y+1/4, -x+3/4' -123 'z+1/2, -y+3/4, -x+1/4' -124 '-z+1/4, y+1/2, -x+3/4' -125 '-z+3/4, y, -x+3/4' -126 '-z+3/4, y+1/2, -x+1/4' -127 '-z+1/4, -y+3/4, x+1/2' -128 '-z+3/4, -y+1/4, x+1/2' -129 '-z+3/4, -y+3/4, x' -130 'z, y+1/2, x+1/2' -131 'z+1/2, y, x+1/2' -132 'z+1/2, y+1/2, x' -133 '-y+1/4, -x+3/4, z+1/2' -134 '-y+3/4, -x+1/4, z+1/2' -135 '-y+3/4, -x+3/4, z' -136 'y, -x+3/4, -z+3/4' -137 'y+1/2, -x+1/4, -z+3/4' -138 'y+1/2, -x+3/4, -z+1/4' -139 '-y+1/4, x+1/2, -z+3/4' -140 '-y+3/4, x, -z+3/4' -141 '-y+3/4, x+1/2, -z+1/4' -142 'y, x+1/2, z+1/2' -143 'y+1/2, x, z+1/2' -144 'y+1/2, x+1/2, z' -145 '-x+1/4, z+1/2, -y+3/4' -146 '-x+3/4, z, -y+3/4' -147 '-x+3/4, z+1/2, -y+1/4' -148 '-x+1/4, -z+3/4, y+1/2' -149 '-x+3/4, -z+1/4, y+1/2' -150 '-x+3/4, -z+3/4, y' -151 'x, -z+3/4, -y+3/4' -152 'x+1/2, -z+1/4, -y+3/4' -153 'x+1/2, -z+3/4, -y+1/4' -154 'x, z+1/2, y+1/2' -155 'x+1/2, z, y+1/2' -156 'x+1/2, z+1/2, y' -157 'z, -x+3/4, -y+3/4' -158 'z+1/2, -x+1/4, -y+3/4' -159 'z+1/2, -x+3/4, -y+1/4' -160 '-z+1/4, -x+3/4, y+1/2' -161 '-z+3/4, -x+1/4, y+1/2' -162 '-z+3/4, -x+3/4, y' -163 '-z+1/4, x+1/2, -y+3/4' -164 '-z+3/4, x, -y+3/4' -165 '-z+3/4, x+1/2, -y+1/4' -166 'z, x+1/2, y+1/2' -167 'z+1/2, x, y+1/2' -168 'z+1/2, x+1/2, y' -169 '-y+1/4, z+1/2, -x+3/4' -170 '-y+3/4, z, -x+3/4' -171 '-y+3/4, z+1/2, -x+1/4' -172 'y, -z+3/4, -x+3/4' -173 'y+1/2, -z+1/4, -x+3/4' -174 'y+1/2, -z+3/4, -x+1/4' -175 '-y+1/4, -z+3/4, x+1/2' -176 '-y+3/4, -z+1/4, x+1/2' -177 '-y+3/4, -z+3/4, x' -178 'y, z+1/2, x+1/2' -179 'y+1/2, z, x+1/2' -180 'y+1/2, z+1/2, x' -181 '-x+1/4, -y+3/4, z+1/2' -182 '-x+3/4, -y+1/4, z+1/2' -183 '-x+3/4, -y+3/4, z' -184 '-x+1/4, y+1/2, -z+3/4' -185 '-x+3/4, y, -z+3/4' -186 '-x+3/4, y+1/2, -z+1/4' -187 'x, -y+3/4, -z+3/4' -188 'x+1/2, -y+1/4, -z+3/4' -189 'x+1/2, -y+3/4, -z+1/4' -190 'x, y+1/2, z+1/2' -191 'x+1/2, y, z+1/2' -192 'x+1/2, y+1/2, z' -loop_ -_atom_site_label -_atom_site_type_symbol -_atom_site_symmetry_multiplicity -_atom_site_Wyckoff_symbol -_atom_site_fract_x -_atom_site_fract_y -_atom_site_fract_z -_atom_site_occupancy -_atom_site_attached_hydrogens -_atom_site_B_iso_or_equiv -Li1 Li1+ 8 a 0.125 0.125 0.125 1. 0 0.5 -Mn1 Mn3.5+ 16 d 0.5 0.5 0.5 1. 0 0.3(2) -O1 O2- 32 e 0.261(2) 0.261(2) 0.261(2) 1. 0 0.4(2) -loop_ -_atom_type_symbol -_atom_type_oxidation_number -Li1+ 1 -Mn3.5+ 3.5 -O2- -2 -loop_ -_citation_id -_citation_journal_full -_citation_year -_citation_journal_volume -_citation_page_first -_citation_page_last -_citation_journal_id_ASTM -primary 'Materials Research Bulletin' 1983 18 1375 1381 MRBUAC -2 'Golden Book of Phase Transitions, Wroclaw' 2002 1 1 123 GBOPT5 diff --git a/test/unit_test_data/crystal/braggdisks_cali.h5 b/test/unit_test_data/crystal/braggdisks_cali.h5 deleted file mode 100644 index 066474fad8a3da42bb00f463898292b0ebe7b3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3099136 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

VsC!~VtS-Z znfx>rm0GSCvd`Cms9(x^8eXic4`)kxBD{*CS%t>TJ!;_RqMG}f^cYh7U9ItX-!BxP z_k^6lUII_{PSH!NEyF}S<%x@y?MOu0$1V@+j4UfWT_=ByK~1ZqCS|}d+IuK8M4$>m z4MS(I2R8}03ux55<=Wv)gJr*3e-S8L^)524t3uDdWN@3{`uQ`H1JCD%@<6HWY?i$Y z){``Mo(WH!$Mb!h-TS9`&`jiETRznQuUA<9eLIr^tM4ZcDeL0CL;HslzNRzqdV(?J ze)bX~h|^O)QN!Glln1W@oc7*(XJzjdQGVz5`1SthbN_Q6IqswTy07azuk*ZK zujljm&=WgR22mTv@fO&x5ZF}z$3>DZtG56^$i6aB%XwgOe z5e&h(U<_I(Wmt>ANnrHcgjX*RiH|++BE*4$fcxMTBAnOyhgp3kbqHPRE8~?BjDymJ zizikrmVoM~Z5oxqGI%Qp`ko|-1%?+2dL*oypl~tSn(fdk6yj=i#7eJ%i_z( zWbDJG2Bv=a;{4#v_3~(-KNU&FoR0kh4?cJvwP=A{3E`T%m!sg2*WpIS6TL{zX*$Ez zY!;cH3;E=q6bWAiKGYeS&7k$!>Jv177LbKOrjKZ3Bsf`9zD|x_gKuqhj&xofA zesq5%RMq>X4)69Mk_)Ozzv|cE28M-L;r!g1=CWhNK}AT-QaC%$ybt}YVq%Mb6#-NC z$vJ=54WLrv!xKIiN05fQkRlaXI7t7yFZ{RPW;P&;q{=i$nLF{+TxKfZBpvnb_YxDq zXMW4z1?CN(a84a2{yKqZXlSE$oS6tM_xDJ5R9#Spe$kEfok{37APCH~{e;i4nPz9O z-~VDc&x*&9pAf_z=H?nY45tJBR9;oX`F}Bf?#=NnIBz&|&A@vIc+8qY$XS=6ft-pq zu%i!ETXgT5ICsLP2j}dw|C|4nZkOU}*U&@nHeI&zcF+%rN+gtw!ChHf%?~0Az+v|0 zTMKs^{ITghI`V(}CH0iaL&eL;i^lYxjbAI~0NqO|I6VxfsGFshH%F1Oop0y*as%uh z+kCB0GzcNixt(nz>&RligSabe1ALE*>8e?uh6$gnv~-pHhAd^{H7n zlK+UFzi1ULk)QC{qppI(pXAebuLq&+-$A5jT&7Uyi91dwFt>=z|Kn{D+<)Mue)X_C zI1`Q#zP$4JRSx}w4=8I4*C3S6%RGX&3$2QDv$2iEry4*57|iPTia?~u<38YYfO zwZipp!9}5L{p3cJI!JrqrFjPOFP?}!bQl5Eb9e3sY|GGbm!2VeJ?N0n5&tD&a(;NG50R)+m} z71@I`G0I~QMQagbqn8UuR2G%Xoa?~a;^gRL?KD_l+sVtux^pFlRPDD(Jt$7MN|MI1 z0EHzrm#r(LL*;&7I%}M7`!PQBn~~2DgouV*e^inNN6cCSN4Yvcf}SYc&Z-eTRBw7L z+?x!mABCx6G}qwE=d7uGj7X}z6MH5EbG#X}UL1X7GL6W$^=bQ;+tKH24JV?lL?|(Q zEHRnZ1N*p_sjje;f+A~hUn@rk*>Mjql5E z=-4Cz(^nuyCpYP4Ean^?Vtap;au$7^a1UXO{QjpzljcY~|4p;lhQ@dIYQsSd72faef@mgwJ-IkE(|xIbNV| ziiX_K-se+09VnpEEci6ex3=LHTV%ue^CPR_vJzoE=(1;`$*&i)xc;9$Ea4Rarh8Kh z>lbH{eXe*K>qr(H%obX6d=dftDS_5Olf59#m+?&L-5i+avJCqxM!+PItB0!CCZu&Y z>yg}9g~p3Qil+48SP%05U;pLs-W9nZ5EW#LxgR6!v<2coyRSPg@ir@Atjc20#GxKU zqd)$g#XK{~#Y+#m4e1DIl+dH@?~m?{R(H0I<6Iw`YdQ;Am=_vL9(LhWBhq^GfLY68 z0&|}&R7(a2KqlGYQo%?Za-4|ONzKIlzmZ4du+a}|PiiE@2Jk*@{%o-|bt`xe(JzHe z_ku9b`0W}zzC_rR?Io}ud%d5Q_hdpB$c;=!GoyaU3N#imtX)SXLbpt>{%i;Ni2!q{ z-{T-!5_9D-=DHO3el=cDXak{;>R4Nx>yv)|>^10LM!x4CGR@<>QgidqU#++C{l9JL zOlRyE$_|~p_WFJca7D^~C*XOKUH<2qN*BIwPCaZZW@~}xXYVPxCe8v6E9Vox`c-5< z{xsPpyb-STGj~3lZ9$(bZg>{EXQ3vM#`2r(HGor$i~{Ddo~tgaqS`eN{HPyp%*j+h zez^0!Dye1IT=s4Vx9^0M?|iz9^f*V9=ZTVT?-&qK8BN}y8bud>5Px0tD+7w5ceE$s zFxRk-Mrv>wb7SHSg1d0tD_`bKL244#wG7CD?@OGwd*tQXwb)Xiq-JZ;wZU~Y!);Ru zxo&i|-%Zhlt_X~Okp4c7`QH4>JcHkG?kIQ0%etJ|0&oxSh?>KF>^#MCji>%gi17`D z;Jvd2urO7nd->c9;+CksurHt${l4B)CUYwv3=Tf1Wvm!O%fj`^QVa7)<7A zaooF=%pHa9@yDFb#yqf$=Zvm=<*A_h(^k{>+a~zkX0>ozAA~*g!2O{=aE^6yt|xak z&bRLPYJKrW8`}9!yZ7#M0{qBbvB+&(1L9IY)z-pZxM#>wrNEE?uf-0Sy!Kv3Q&Rjd zly&={s<7%=M14H`B>j4UU40pne@rZ_&4a6_pBUhQrD$t-V0LmlV2?$<{^ z>vX&7u*@phP01M_F`onvVT1QAMVJ%#Z~hSdt3L(p(RUVYo1^EJO}3T&LJ%M~8r`bQ zM(9=y6eyi;0LM}TjNqC;r!<&Kw0Y?W!pK=APTvLHI~4Z56eekpHu; zjAFds)=Wyd%B+b0-k!DAR?-g)J4d4|r`A#UJ^G0=gFVn3xWlZ4a}@SB=4_qFY6W)A zZEhM|@8_^}vMv3*OdZWkASBRMe(q|1+Y zfBjfR29+)(LX9=BYV=~HHf{h_YP$4BV1JWG@U|oO2gcg5x%rs;xwTSX{;T(lucuq@X!zTM`TGcb0 ztMrL_fGoWWDa<$uyq?MeE!)NOB6vR%V3s;}SZow2lysE{I$-~J-my9j{G41uTB#GH zvJ48VZ8g^_zJv3$73+mfthfHtU7*>Mhvu$LQ#RtB(vu&`3Vd$MC}ZV|U4>LXBxT3Cd(#h^ETf&Oi3Yc=D3JZ1^~6%&C&%lM14$W@rnL>@}GGBydX ziykP+_v3te@dHe3CtDEliRk${vkA!AdcBXmava9qz8uhu9RoLOsyesB3lJ|(8+vZD z2QKYy-yJxz3;{dRA62#c(4RN0S2xYOA#8-}HhFj>y2-5dLHBtY8V)9ICQWLC8^p%j zecqwy{ui_HX{k`hX?OpEd?@7sc*dx22j%C z$>sy*V<0|9a=Q}e9kLRKD_s3HhHQyaY-A$mk&aDuo=8^-&TY#&&~pPX;f$2QT7TD& zv7?{Mx=j(>s(o@W56_4F;i-M{m0hU%!rg}l>vQ2(htS*XVYzUxY~R&_!}7 z<9d^$?65O_F52u4xtV9v4_(&@lk;Vq^;pglZv$qQT`Vt|_ts~+NNgsS+I+5S6JqIE+j3*gz{WIr7M((U&KBD+i zueXQmaNjI;mCFPYz_9p3^HKRFl&+(zhb>pYJEx z|E(vJO6hxiyk|l6E@!NBweE)o~2DN$;oinP`S+%Ddt{=Ldk4hT~KH>vhy{H1W;& zOasmjAWxcCuY-esyb2SWry=W(ftTjZ25_0{L$~pHpQ3-FY^jd@`=N`+7_om%L6V%~ z)g<-}bTTw(2xlRo$U4SKw<^dvXHj_O{S3}c^2}?dZb6(!x>%AOtAO`#%Xx@fg9rV} z>UKw0P-Q>&4iFF_>fJ!{}zbE{a~@{_TwQ z55huojAC^4;oGQ$fYw(lMDT2c3FdJf_RMj;faR*sSsX%Bttf zwpINi6kR7y<}q4^_-#Ep78C3bu5Bni)3E`EtRp0PUax|i_ci*&u2`TtF;9FFb6{8l z*!|aby5ZCbd2(7T;P$wv1uB10+1OZT zfVo3=tZp;15++*0R+WS>|KKe{sv`D3CXFXj+rDNZ==RE0@jJSp0~rd`dsz2l^{(CK zr54t|z3mdcri!^TpSMKEUrxZBLhx!^9rnMnF`fDnfb(0Aad9k`wgT^Ck#E; zuaLt$fI~xC*PE^T(c|-M(X!Z2)$pL^hxTj>lw?ildh+0Y)3FuNQ$($}E;qAW`Emf1 zIv4Azx5m)GN}tJUb0ee`O&k-(_fa(gPu3m&1^AlAS?u?t79{q)YPR5?g>U&sY@6y< zk#~u=JbytANGD8|2VgG2;?~-qdA>CC_ovYP_X;%-8Fb`q8s?-Y2VbQ!8(T)ZzZWi*kD2(lTI+1+ddHup;V=zpg0yEZOfABIH?`EORooxv?o6R7 z>O-;(!Ocz{MQDYLN|N>*=InJmAQJeF{X|EJnNJ%HqstC%Vgv3eP;TVN&wB1$9QTSH{s4m*WJ~ScI420 zLd7#Q9!kv~*0T)Y{frH1R2W?)S`8C>%ke%I#FSGGHC7Fv(KE#=A5F%9;In^G^r7V<3>kG*cUM z{31V5UgN0ihZlD|PEzDVfrk}~;zyxLB(qS!`%41>5rJ%VD;cjp&qHSJ>|`SMY8Sh1 z%-`D86tt>xjDVJy_3*V9*!ML3mc4~^1FgAVar*co0{-*K|JRqhkicjt%TW*KBztrV z!zWNGSNiFRyDWs)!u9b)%eLqtqRGp(bj12)QZ_zHCW7BP&$&Gh7qmbf&1KUt36Wkd z6unu~kU(%ytZA!9H+47V8SY^2;`x`h|6zUH?scDb%ZZ0WEyTx$h zewxQvibZY<{Gp{~^oVJLoU@M`)FTGKaaYY@tp@We*QV(8?b=}VGC`A_dKPqr+4$aJ zUe6B`$K2-2)gblabUsI63uL7g`_!;u-Kt@zvo_{SD(JmrC&BuaU$>J&cL$ddnZjif zE}Z8}bkf)lyps1+40u+%xHWuV%oKmM8T5EO@S zu!^e8Ah7@niR!UNRD5<*EY_g}l(wHvJeyg9wULacR3w~Ax$lfa-vue91B+{Dk6}IHfL=BfSgJN2>8}Iwqk&tMSZ702w>sa6>jXzhIy2f(xt9u$>tsCE4RkCwc;I;w^|rv%U>FQq z8%n~*<3YVJy}c3Vx(h2>&F{nxfjlJbl&r?VaT;q|OM^{FW%qS<4aK=7QGR#H1!7^d z#3(S!X%;}Jttp?NWW=_JtD>X9UFmY%TrOn|K-Han~h9J2_J|e zukVB3`_x&lp-4C?x2t=27VAvkR+fy-te{&pS8qjJiiAI3Sqalk?a-cg>QH0#D9BOG z#s$BL0EPeA9~N>m`?A{M{&;1V-k+Tbbc2m|*jI|3z!7kBBbnF^WnPkDKW=M;T#b%3 zsTna4T$kk~@Zp_V+&B%?=pMia?CQIEExDG+< zT3ZuP2WUm|Bjw}__%1U&{<^S=lFKclzjM~Xt7oa-6L8+bh1|j6*G$Jx1k4%zZ)NV+fw<&k1jE)ee9_#jYQJ3wdSA~C)6~o$#`JxX&9|G8ZhGGX z-HZ9q>t$bkfwBZG6%|1 zuEwxeO~YHwU8+Y7i{LqQH%y^58}8~anI`P(hdy^{%IJi0V9pDk*e8<->6Py`uu==Y ziyo*oY*<6rnwrY$rZb?uff=mt4Ip|S>kDrwF^?q8SK8M$1Ly9^-kD&?LI=ptI~fr7 zp_%&uxfxNZP_NjLYPp>c-!6qSYMKFG^c2U^=n2qdZblWVeHCRm#Lx{9B=zx ze_*;B%DMW=Cf#S@(0~?O{I_VxcyfvUI@Xg?(^ddIy6QPq7kADD_$f`7Ch`+6sBD_BoWA`&HcLE;HewvtDb?=LU3zDMgcd z0p}pw*=y&-kHFVo*H$ds_duW<@Aq^=xY~wb zvAF3OALgslu+*#O-@|&bra#JI=P*CSp4iy3aTPtSIPLJhu^qA&(izqK>(RBsuioS2 z=_tqS(Ot&Q8o-oBfx^Gei=Fz7^Z~Nl+n{7jqtdr4ZkD z{M{#oYT#!jb{53zzS1@MND1vCn43G&kc#yqDtUb;ozfRU44oGvRVo7WgQrDp@jmu_ z*M}IvnJ$#U6u+1gUI-sm?w{1e&u@nU^DbGbD_4nv#c_utsa~h=Ez+4tAdg5)G1=~HYwNT$Qh$$8{ z_7Unq*4nBQ3oXUy@u3gOn>a^KY*zPV9s%<@NDn!t()57ZzQ!63=2W;N@#egq5#~1T zPw5bH7=T+mEO*}PB}3eTu)~hS43^c-J@FnK0`%~^LPuK?L{0pRw{UC)xq-bDlSHiJ zbGR;loHr3@ew9}f*(ag6{pU(R80F0s(~axJfHPOf ze0zN#ayXvZF!6k|8G}$ zv1NS%^BjM?Tnb|%Wa@he+|ii9J{|e0W$qSW9F-J*D=-ABt_jzsiyBaBWk@1%>QBg< zeWH6%Xb8SqU(3)}@IVX`6wy~?r%>K|?RQ+~`XGbtd=&ShB{E?WYkYrv3JMn0s|IlW z)7iSYXCC{2iSo%lcDME+)BWn|hcmk&=tEGk5auD@^j#9~#`C9HGh;-RstaU#iR{j` z3_vo^WyMG28z{vjZ8h*?8z_Ibx%d4=BT5>6k?|M^ZKIFKNFeHkPL#g=$H7-IUVx#lz!b3niAGzT1vW%4|6j=_w$@tMx~Md0#GTsg9y2_AY} zf6MT^^6E8m68+eP=>}l3-Hz;K1%jR>q=Cl9n_W^|f4kIIId3W41Bww(S3KX!URgYtJ9$&M&5uLA^tJ)5A5`9#jrWJgb%I#eoJYV%OQ4<`-zT0+dkHH@ zGy|iNxmx)L%nKmB88?^q4*hjaOSw}y2`0q*x;Fa;An<0e%dli4ilTJ&DT+x!YoxTy~4#n>{(rVD;3rwA^|PPH>jibZjl7nW~|~>Uxc^dHl})n$7_z zNe}tz{$mWW+&=!6y08}R>ezYdeHegmVe}a%rq_|-o?x#c*59xF^x@sZT+-^z^&IME z+%GN+eKLQz3RE*3nO7^q(45rePx(J5(eg8fM^Odka8KUy_aC`&6mjpIZv4_5`grsF z{77sW=-uxsAiviN$Jz>>^uEu6+PyiEPab8kbdK%oUn%UvI8C!}RGPzSjzc^!7e0{cwOyp|g_gpCjN8+*ps^B~IesG>qItvRd6#i6aP_I?x!uY=If&IXD| z=O<$pi-je_Y`N^hB~*IwcNN zN8uqkFn*wIL>iid4aqq;S8O0n*yUX>sLC8l7mvlh<%{dNDVRq^ci#WRr>`BLEb4!- z?8Y*1SNU}4)C#Z?UT=Y}6zNn;k2P58*kUJLUPhN& zIoVeF8(?sj7vk4I>P~;}y}&LMwV3dbRjV9?Cnoo7?ig&b+?;Go8|OQ>VtW3@YkiNZR0RBuYNC<;?^3{CN|3PlfnE%$JaYk zytQa;XI$tE)>Rgn3fGL?#CqTJBWJ!7^&?k5k-b;S>)@vGS$0J>8A6q41`CVEp!yNN z$NbI@6w5L7WnvHeVrnU?(pc-@CYxaU)2R*A_4|12!y`%H?Rn?8aQ7(O`&b#fKYwqD>ksY3 zVea(*fBnZTinF{EDmZ2VTspKZm;0@t?zH_S+AeMaJz2@o4c2<>x8_z}*u(nW=UNpX zWEcsB7ZVfK%KedpeMvz~-6SluP6~E2VP27Im72hX8A!itCBnmwbM(Cf9@&xNeN?3H zMPuAg%0Bh$+rY{iTFw1pqx-rW6g^1>&y+TyBjGnrGgVDM`CI?Xx$iq6z?(DOEFJfe zLS!FgCe6bY`WWXsmpY-P{E@&Xp=FrV{37L+(vMCM8ONFov;!fPZQ_nYD^yF}opg1} zgJbtsufI-ig;;}*C*Sb>o_zAi$(prgbkiq|H&Ct)Xdk`kJKT?Rg6+aGIG&9mx>UE^ z7aO%O79R;0s)!U zo%L-AK$W$M1wCkdrnkBuv}WeF3T+V?R?@gZeK-|DnF|hB`d-FljC9bty(y7 z*|EK0a2iyjT8Wfimp~iaMNKO%A;Wy@Gf5frn<7``#U`T!L%EZgY9 zIXycXf1C^9bo$IpMOz;t4$%qQR6vOO|C6v8T_N-K?hCmwG98<+oa3FWBTl^j|vfc5s?wODa8RB2tgHq>*1pvMxcWu=RGA$A)Nf{Jk; zGdJ7Vkl_enYQ9>wbkh@YD5*)Vp-B)kXV}TvodXWv@xJ?EGhjsXn)7XY3s~4rw#LWy zL+Glf-}F!uO1qVA8r6#X0pYD`0Yi9yN=czl9zO=ktkY+gYvzHPqh~b6vIBl)xd(s1 zeNQKec}iEd8dN#oqgoMZikP<1(`-aa_}$a`z8Ri`eAGEgf$NE(F$!6ansLsK zYa&xaB}A`87Jt_pg0>?C6|B@a&&6RZj8(J}G<(N4tP}d6-j1d2x8MfSitBQZ%c_8L zAwl5`Ep1SGs%bFLFbgQvd#PAoR>08FTVXXVOQ1V>a=x9W3vRcw{UYbBfW7&aKjrK* zkm`{l5f!xvl?7g*xmu+V=dq-!eLon5@8}$*7M((m^u5-*<%>c8*%{4m`m>PG828Yq zc@-7u+(^7hTL|A~)w+g5*I>I%@w9z#7h=#!BNph!e#e0QWM?S`QHQB$r^O=9wXl)s zSZSb{-R5S$F6Av|fiJrKC{a{sU&qZ%EzyVgC;fbnoP-*V@EzYoxDDRvlP(7#v z`Ozz#RG5FMyxh5x$gqOC@9z(oxLONmB8BoUe>3_d7Y zP{aFyQsVDtoN?Y)5ibX&&|oXDHb9}>yA5jJLle1gYF29qoyl=6{|<7r;Py%|SA|Ir56SD4}O&rqM5O}9OVMS%zT+wd zI3MEPB+Z`s43x=DGK7A_ec~IO6o-@xAY$Ki&ECyfaJtbeud%m^LPKs*1=V6bS7Q=o z$~~Ny>%%rJiuLvsTo-v?@!>wS#@F*!ha14yLjG{(`ZO3H&n~~zkqIjQ#z*bHoL=_8 z3&D!(7D#P>2P3VVB?KMr{>bEtISvHrev}<_EpSU$3 zt>c5e%ViU=o6j_v(zy;b*PrEuZD=5(Ui!97vMEUIIeXupX%T)z4oWci48WBNspel; z&%CAS_<4JV(>Ouk&60e6QCF@d3G=sWa*S+f=E7xuHKH-Bz{`MX44>WOf@Bs1-5 zA3NqNt?<*=jbnXq)KoA3fdxoVu1OF5(+s)!8x)RMCn!JB{P>qwKl0J!WsX(F9Imq? z`)HlQP$Vb&ksbCabTP}c{Cs3B!~@cjN?wClLjD=Qy=9a`aO<}as0As*gI5FJ%plp} zl>kQ9Cghzy`flV@In?~A$=bT!jBGc$JiO)7(Z#v#QD&SIaLi-h(1p%%Fl~->X~Vjm zhG%6(meL5Gx4+dsg74G$ogr24hZnJ~JuN5sS{_(%IHXd`EyJVkS?=PJ4iMxp*r2h( zeHN7)JhspJP^;-1k3XWND0IW|C5U}3-Q`Xz5PiITum{za#E!^* zHn)~m4^MPGIM1^FL}N-D{t1*v2oFWSKlQY#N4l<4U#1^UK;*rX#xJ|KfL&*nG=|g* znY)cqmfB6ilj3V_PnhT6wU!*oS)6xiX6^8^|4$3t=Qs3UUTX!~^9HmOF@IG-$l@VU3#_nCvFqbL0=+@R(FbYsa4pZ; zfo=i&!t-yC1Q%wN@zHOt_ZBnh(e8X@<-utDvV* zkxdMLK4|SYLnlQSc)Z${n@=nTp08m#Q#WQnsPCoFExIL8i=RBVQ&I%(wNF#;wDy6W zP|+Nf=QVoJG!zxN9;}Cuy1yHd__~XgOOfa>=YUX$y5A;q4Eip;Ut;3X6nZF8Lm6-) z3zqJHpk?I@a^d-H1MW>o#Wuag@kb`8{kwjK|E`}>6CXPjiwS&DuX-KwR1;-HnNfdU z79uoBY<7id*Mo*;X^b_VmnHT=(nQB82}g`P|FR1-Ap7hdGS$};ARPGdg3aqqxT@uv zkvZ`mnKg3UyZvzzhR6t(#g}`bRW*idO<@ck9$G3s5i$>9D;;NPC|g1Ny^Ez|*$j;C zzCXU@+5%SAJjXvv*TccV`rkZ^eNf$$@ppx!6nvkNGBJdfLx}QaM)90M7(cjsf)0(M z22r-YFLq_1+EvTfbAAm}FLX#}dMqP#t>aE~B3QS1!@YLp9?qYX+#r0xI#>o5uCAJ& zcz@?Ko3q(k1KQ(H;;tu8gU*q`%2PdspsaY1yz_KF1RI?_exqj{y=vCb{}f#aTQJKa z#2SO%7k0XMm`$R$)?8hxMFmjoUNLNYZWfLBwme{TY(?I7pZ49vn&<;*4ogE?y@-KE ze!$kW5Y3-!QqU4&(o?M?=b`SpYI>Q#dC{Apn+y&R82b|o6oo;xbSsf#zbiFCad~%Gk%rhHCUmiFj zZdDB?%R0%12{;G8M_S1S?{Bl#o*mt~HH*X^4D2@DZ$+igMb$g|vf%E&-~S(1fSqvh zLY z0u8oApLeCWcLX%q zI%U;sehC6^1;}2A6CtSo``mv#hvKnKGhZWJ&=1zkNlLs0=zXa7Ctp6o+0S_iUr%)) z2jjddnx8=^Kiw#=4t0W+lerY9bvsae{}cW8d@juIYM!l-ZN&MkM|Zg`FrOd2UEaVaici^Jv1DQ>>C^gk*U(g@8cQZ`bskIBH4G?Zoc?6_0JD9#x|~? z^ndmKf5-RVc|ZL%<*1dTF^ZTPmQ{1P4&O}WBNs78s-`u1@8A)fJ0du*U60ot|H0Zs z0j?qV;F6H4U@=taAEKF z%LnG2=#DpE?5O1zcqmq*dqKV%)KZMKd~4f5Kxx70<;6?{I9$fj$o`=@@XYcD z)Grn2_X>T72mf=P_&cMt&j{H7`Qi7y4_KYyhtN+Ux(9p&k8s0c6{AjM8bHo<%C=^yJUW)dSHcwX}`2MP8O{X33_|K2I<)|!n)EaCK3cimspPEfS}<;*Gs<8B?%d=?E8)>^Aj*VLQHm| z9(0bSe)~II5AMVig~y88;EtwtVE8~avMc*b_O!GW8OzYPpCiK@vbJv?{W9%{X7J0E zOH{RR@<&30JZ(Pc{QJKD#$z^9bMNa<4`J-Sr&__2$B6QxJk^U;K7thYcIczbTA<;Q zK4|FE4BSG7Nofj0a60+DxLry$YNfvQ@k4YoLi}{6ykxpzN#IOF>|0#lpr+|E&-($9 zb&jM>@#%1y`jvKuL=kF?V?O^}9&^Ga2SoKd)8N1J``^6H6N!K6@8pbBUE@zHiRvSk zZ@<)P+xZBN<~;l=t2kFNqD1uIMk{cuKYhyTKMpP7lHa1r%8_3l+jf~|D-ux)zDxMp z4@(SrEQ!9IAkseF&*?e@r?}*8e#&P+iSU7qD#~G?*%KkFB*!|)6$w3IH(bXqu~sx! z9Ypmh^>-5_t0DY(qLLOz8tDEzPyg|4-ii&$55F)$3P%iGbvc}1x-GC(ZjGOCOyU9g zY(gQJbo)zMS>t+PtTN*+T7>ggp6{>gszNq$#%!8Ht!VN$U4PXl?5|sH4tiwK0iu+S zO;M+Q!1cvVq;)J87{A)8MD8C(CK@Mc6gR42*Xc`~l3g}bzh0mJkX{TSRbC!U3phWW zcf`SFB^{DN<=9y)I#9J#jQRnFA80~-Qq#6N9UlG9cv4tAlT1dfi3F#%7B zJG$ZQUyO$?*&O2(AA^GhPmjOS#d@Rv8Bdw}_4N-4K0|M4$f{_4pPFoY?<)*f36qHZYu3uv@=?~ zd@>^Lo*_!v?{7P~EkJlnGx{?lE*mC@-12;8+u>z#2fZQh6u7EY(MH*oB6Y!AWA`)L z(1^Nvw2FT(=rI~htdG=#*t<&67YeOt(C7|l!csAK$gHw1Jpg7UuxyT_L4gD@L5;0v&F*GGNpo;N~312weMhB=`HrOkfUCspe2g2mSxK zUJI$q=gLx?k)o;08%ZuB^zZ|{_#29l8llm|_bjF7g$NzrF47p^EkQ@KT0NeNwL`3$3eB0SDcH%J&j`f(8Pi|f zRgc5k(DTEO4hl|<0He5Z<+M5hiVmJz^ z!@mNKY+ya~{~U*`kqDRRhBh$HvJ_mw<5ZK+BRo>#6k)#fxz`t!JVZyh&h<&B9i$u9 z)kL>_B`}gI1D+a^=IgYCL5}PEynZRQ`f_CqX33~SG(%ZCLA;RxF zg~u-smZAqIZ>)Oyw?p%W#37x^c}UnywsgTc6EE@ujvioYM=r4{&Fm6C;qoN0h=yz} z*7dl`($S3~4);rKDvf0jX?OHAr9&+W@SpcK!1XJuqaVNbTNZ%PzvK8%?<{MP)9_T> z68Rs?-_P?`8`!$OJ#82lB=A~txYgm~V1IVtJe_tYJhHyx#?RCZs_PqLG4FD~)jOkU z?-}+JJ>{0+Uc_~QfB)~pfA2%hyLOea&yXtltYL7tE>L`9vzrW7IUd?R{%j{dMBE&LI9Y`EF2n=o2;Tp}wV8J@$P*#WQRR&Rm6GxhX;o>po%Ww0+^xyII z{(B$K`DmjbsRS1VeeCQa-h%ZPd*W7QAwp1jUW5d$FTZYh#s1i982M`cZl0C@3DiRN zjBS{^HvOk<{F2X46cBBvOlE?)dbaWs1_e#1MA-8DcYOT=zb*fb`Q8m?t)~p7O=FQl z;i(G-@jrl<&R=oiR3!-96|y8S8QWdm-i1PfN(Y)Fl7@0s`~y8VF#{nF8nHuU@Jq^#1Ut$e-drflT%Z zACKS|d=BG`)?jP^Ll60th|@pOm)9oQAMm;^x_wQf&Lka<+}}T_>NSXjZWZy9VLkHB z&hD(1ZwoYW%9PvZ;eK3lgK*zc8_s3rx~-NShx`}$}?nT6^Wq9BCZH)0|G=Dv+q>Exz;c9}<$K!n~$xDHV^7&*u{{0sdE}2{M zNSD(64` z|4-VfB<+PzLX;57BP}US6&gYm(N4QGB%>vyf%e{mcF*?SdylJ~_SH^&pP%#b{+{3Y z{`2b(UB~Ijxvtl9JRXnx{dV{19vm>lobO8H#}U{9%^amm8w+rLQ@E?-n?96=oL-a5Amq^TYU%M;?6Y_budscyNV6?Ueb&7hnY(uW^6XCsNzsr<-=K8xV5F5%b;k97KHFz;t~97# zwe+Gsv;@`fUl1(b_M)}SjQ#oHsbKc+{rWGD{ri3KxSxh5$SY8PoKwyb&R!vHjmr5k3HoFqe{b(E*PdjMcDcl5Z&P!}Q zcUr*d^lQ;D<2v-1Zoq7`8t2{Xa~t2#oQ1VVX)Jqe+Tc+@MY~%-B~*^SQen}?oKALU z>F0TPf3-?#d?<#%mh5QFxEh{^a_xV}8rqCxuNSWpwesP&IwzFzjDz6UX|Mb8BdF?S z&do9Dd{|8DIxUNNBT7RSkL!-lBZ*Ct$ntM_5S7Er^&+?&sUJHbEO4zIdUt-4wgzE7 z(L0hoCf50A;<}>T^X6_;%xP~l*^v!bZyRgNeO!d&3&dKJ7g)D`j%hqhF$)$>vY!fE z>_c5^WF}sx5PEp~#MD{4On5~5)|3OaBbJhNnm}SRP@TQ*)WDYs!$vh7g=mQ|7ZrMX}bsH72{jP=5c!)G;3=g@{D zb%m}&4#aJ$QBG_BL>Kv=9h;TuMwSLwyH%xgptpOOkYHa0#teh}-ib4CJG^Z&tR)L( zTc^m*k+p*-=}56DZ40t{Jn>*bJPVfN=s$S|wj-LkwQn=WTfiM7SGY$rL1|tjp#5Vn zDsGZ}kfB$IUezZIsHJ5>%@v{aJN!A|lU#y5+nC>1A4a>pngPQj+{bpwm(Zr1*g&gm zA9Q>THCN(H#`*1Kwg=NzpgM)FLOi((2Kt(J=&mF}*y1962w6MwTgroPrQteV zrxL*8-*fPvF5~XU?wQn8cX+;1QEh7C0e_R2jyoChN{(l%PE_H1OBveBL$r7<6qlAU zxH?5DdAzg9ncuA*X&CfGXXE|tyvQx>i)4Rs&UOe({^!q#K4m<1IA9V&RNoEAq~e^S z{?L%Qx<$}tRY!+#j>LB@bIKCF3V7TnSM{K;1--V)RIo|QLh7Rv*Q>HiK|N|QF@AIu zat#w-4%p6tgO?pyI87<=l~Ys^+-E?kb=`F6ZVOa@5G|$7DS?@L_nsyE$V4uWf(CCE zbR*Jm!5+GbLTFYd2#qZhK-0h~pab*D6q(J9WyWxBKwj;;KSSyy6)+x zlsUjIy&O*P?St3Pc+-Tm3264KG__pe52$3|Zt>LbL)6oHC4|Oebl}_G9bMBO5V{&? z^eDU+3e{uY9xpF}?f2)4J}u+?Kl!~s4m0<|$M=)c*V)#P!Pbq-vLxBSAph4xUb`I_ zR4l^*`y=}sd)!zivtadf!R%)65E6bfbWGt40cf@5oqttkfpo|lbb*ctVl1w<9n@Wj zl_6a}iGvhvRdY^0(=znuL8gLNLvqQw^^ZnXmzjYhZ!;5iH{!u+y3A>_I}xSMBs~c!pG55aPb`IJ;(#`eD{U@f3S`DT z+`^0pQORl!56}5nsNZbgBaG|7t@}->mc>Lwk;w0G>-8&MW3ks#!(cZ@S7v-ju;*3nyd2mOju* zRu$0E!hX`-ztg;$W$<_TasnNGU#jn&oMW(<105fmRlAlFpf%(uois{8w}$f@zJ+xo z{i>$y^!yT7zoN@66E=v{>kmxl;e5R4rd}6i=MpHoCFm9tJ%g?)E|WR_Y(f*aKjcZd zBhb^XG#75`22ovgxzQ8(kiosO$?x$46oX_JMNW)?FL5W!9*v+u%h#z_b+Z5O?|l-! zzJKb`6mk_(NZmP-4QEOo%7s{B9;enUec|97a@Dg;jeV5`K4%v2+=d9LPTz{MJC3v(@ub1Ku>$n$ z^f<&`zOLR>NJR8xNOw;uX41^RLLSq4hB|ImU9e z=FA8%+0VXyFq;VVBV;D3rBhJ7m@tKngMb1J_h+pnz||Q&cWJ{6uvj$@a+K<)GUfJOOdpW8fVFL9Q+j6 zxoe))hD^Rcd{+Ai=T{a4IZ^+Nfeb%EwT_oFFznklcGPkO^)n_*jEcrUnB%W^8?_4{ zXPcVAleYx3Mb3M)enf+w>!JDpvk`b%K{maeJ_1;RuIE->^KA2!6m8@P!p0vq-i`J44YHppJf&l@32ZfFv z_{#a7smZnBkw(E9s!Lj~Ma2`AJZ8$z_K59Qy45g>B@ z{i>N?Ieg&Cxp{p#4smbBKj(3nLfWi0j_tK&FlEhnGupWy7+LhxQVLd)OL(kN4pk{E z51h;8%I$#4fx=^Ij?Ji4BRZTduK@ZcvscwIXGGu5Bw-TImpj5aK8)ks%9rccWovQ? zDCtj-hoRs+`rsH=K3ts(RbnPgJy;)5xXSX>^cUt$bCJ^hOv?q`2qLT$o z9h@%quQ8YOjB_2W_aL%2JadcAI3412i}dQ;rr}Z?>9zdId1$l?c;&X13OxmtzDQechaq|D>aDsX+{todYq8v8irA}*{Y0ZW0qS#m=<`Vse5e*AJbs(sR^ zBGs1!{Luy*>zOzoV98m?c(E9(^IuyB z370wJZjD9MZ!W<(%Nh?4-ZlGlQr19)(O0##@HM1WD{pH@5eFZ{1We*JN6_ow(>bz7 z=b=!cSIRRo7Q~3nm!i$b5aEQzyW4UjU?Q1lFJ_7JHQk$?B;vc^y~NSxGuRi$=BlZG zUo#f=I{#4?QYJuG$goqJL=F7mvA!^p5eELMfy_F^(7Ywo)E&p&@iqW5CcL_j^1lO&&8!ut+fqf0S5 z&LNrcqyL!g!YlY;`+@i7ohM*D^|Iuw5`&}-HJx}(Zaor@Gv}a*ABQi+d$OO*Z2;-* z&#w>8dm#TDOSK)G>v>;P>s-6|Bq$pVhv?z;9QR6LPv`{#dViNScSs-SL%u%6p}-rA zJ{_`7D<+vjreyM0t5w=T$JyxKZTclB(pz%AB-M+#XG(QD5-s4u-!>oPi$oqlgeg`_7pp$)Ax(r@V3NVdbCW5c@3YiYpQA}*Gozvs{AAfuD zmOIu#Z*h+NHRx{vWx{vS-Q5zf)tJBI+cgL@7os$)vR82qf`MW}Pzj9CeX8I6BScfPw)1Pg~kLagQqXtQz3t#tDj z3ipo{K*9x()%`{B3fnjY7`buk1dO0R(@9wg9r+-(`ysArrUx!>NN|&UFNLO%_nW6J z^P!e^`ntw@0vzQrJC=O81_*CQvL~8I$6QWInj**aL5F<*jHrB|t?JX~`ff=G5KO2{|!40bPqvYWlenzDnmiapmvMx*0F;Vfw;%lrZa^-67@Fk6O=R2Xj5$2_#F3o0_)kw{coOt58uh~$qa zHi>e_0(VokdkxNempH6e?rA>@Z!J0RO=16*B4w|qBIez2tv{xBj9x^C`mC*UPGMiy zs=1?IW;N))&SI&hngNAw0Xy{*QSc0=N6Jld!N==P<)NE>m@9XEC$20K5`y8LcFGdu z+ObuBXkJF5SBrv99*x9#O#_{=StGzp8umG6a0DJsrYU=PM!<`I>-^Badq?BIvGG;W zdRXCoQ=4Zrj;?9D0nZf<$?4vv34Kf4SCfcVv@F*}o0IW3JWnu4G7+Y8uFf~0uaibf zzSHCI!{YM>@$?3CQgEm*7vf6qkn*^zYM@jtUM(c2A= zlswM#`!%2!+|#10&$H130r{Lg109(Ew6|&Sz!H4hUL`e_=tTznD<^HNn*Jw`NLjVI zA8iYt)vS*q0Q+;w0o9yJP;E7_=Hea$SC88h;%~7ZU^r;u`q4^o_5SR^zcL2ZCz#P@ z8uqW>AE&oo(|_+?!@jg@{AXS|Hp4xtk3qH4<&aiY5V!~X1{z-mJmxE!1~F&h zXZ=6RU_djfG|Y|&S}aw2IAfQPRLP2;y-yk3u{*lbJ37F_CX4x{3)X z>pk%Y; z1#)33=GLn2!y!0+Yor+&uOf=$cfXY2x}7G6w>I=Z4(dH?m#_G}7d=sXZA0mi3EU&+ zZcb}2!s<)?eQbU0aLKdkqE8{zy*XfqMo-D!&;!`k@zD zRQFOoZpud#K7{+QHywzoH+|QSV=i8HVzKMnUXU2pIj!V|bGj)4368iQ_(bhMNg?M5 zg#L-k`bLoq_xkU=w{OvXWF*Z)0KJXI|;6Y%F5E+87{iOhhv2zua={Vj*4#jZ_y`LzZ}- z_>#^#%5^K3;7^VLvY~vjDzzS%*&%+ho5y)#OJt9{6=Q&#u242Lcn0^;KIWf0yMnSP zFJHUzJQ`wi2SW3SD=^P$%q#M?2Wpd3R&U;jhO*I|%$~_L_)NvVs(ia2#twabNBt!d zC<=xXejjNE$NO)CHz-<>zS0}l&wi2MXXU%qs!Texf9m ziikKVu4+}_{dU^=-s_~c2(bCLU&Q~r7u?X|r>Xx?4@%L_*9KmWqZjMVYb?o}l2{$s zb>yBYqLN7RVUw~#A9!EzyQI)c%I)6dXu$hL@Tr(!?!V*EIG3&#WBUupi`d#r{&*mM z#-O}KU+fQ+PzpPlJOiOavGO7uZ_&t*i|_r$N#t!%sj=ob0cJVO>Cdr$K+os=@~|NR zQA{0mj7}T_CyrjROXnMaqomKf_e(a|zZuO*q8x#VOZE$f8g+=iIO9}+MHV`Ac>J<$ z+yInb6`<_Aumm}g`o&+Gdr+<(&$LfUD?H}Iws!7uU{1~-5az`^fZk$GzPcueuqb-O zkLw-Rnm<`jX`A6j(vQMYE)T}z^K~IYFyPQ?H7wkTvml=xgIh{R zhkyJaqJaQev+2iGFp^Dn#FcXfIoQ1C%gAU!T7Rdk9~4x;x`-jQjS~U#Oagaje$U}^ z+u^tR4eaj-vHECgNdy)WmCu2gTatK8_{B4uQiz+YeY7alhr*PrtR*W;kkN5sSLRL; zI5CmGysO&_#Zfmm7Pv}5%>C}UPxeJXagfB8ww8eSL?xZ?x6UE@XUt<&y9GeAH)+&R zZ5CQ$e>7BF8$>zB$HI_C0T|M5X;MY^LQLb9e<9TxQfJz0^%UPb;&q!Bxp6%e?7e0l zUDAQXV|Qs1vT9V6R>^>?fKr|HXWV{ODU$HwAOx3Aa(fp(9J^rlH`2`k@|R% zAL)7FOvM7|D|@i2U&{p7P16)N(rolovp-#aq#J!Racp^5lmTQqCE-EG#?X-@)zHDJ zT2%IIdSV9m@m+*(>LjhV11j3(D&=TJqlyd~!AFw8^U>OoNykMXXl3j5oL+*ZPbn!w zjj_P%vE0XibJ+J<9^dec>4C{ey`yuOe^8L>;Vq8yct1Xke7-0*496ezgp_V#p78UJ zGHxI9(Khd4VYwM1A}j6NJvD+kkG}QHlta}hn`S&tstV^-7uVlArWXmZAM#^=(=HLWI19Px%6-1#6_loQmgL@M1layR_j#jOJ>I@^_26;R zNt&mB9O*TtWgNW9C7E7sY3Ar=inP}b71qw^qiCVo@gqSLk`8lsTavI|C;oucqg71; zQrFdC=X6^F&c%sm0p}Xfn(~R6qoa5(#Fgcr`(+k*Dd;Guvi%VM?N0KSF_RGVP?Bxf zdmP-Y4@&0UcnqYxF+o1#lSqGLI@Q~D6k0mZ*py>kyujFc!AwnScjq zZ>=3Y?yLR0waJ2gi5nO1nqQk60G(Ei%y+}Q`#;V> z^TV%w=U-HS=bFiJ>6bY7*~V=xzibKhwF{k8STBdsjKVug_;YA0So-ipANQ-z91`!I zE{A0L&o}7tbH;o)SpF2w#XTg$s6B@71;aIhG6ZT7| z*!8QS?c8>+(SZz*EVf~q*2Me2?WMka?LnkOKGwkFm=3C^`d>Nlj-kKT>r{JAj(|DG z5uz1WDtL{YzJKOy1Ly=SR9c@{M;G*lG++9s04q&xvwVIJJbI9vuoyWDhv~Q|oQ9IY z>(7R4tP=JUHU0Yipt}bspV0NzUr&I&qOPMQ{k`BiVEG%-6a&59O*c23f0g@qCe1~6 z7S8x5#P8i*L66K>yMt$9K~lqW_5P3pqBbTJ=ZON>6;Xe|c5k8w$*67jj-ywA!@ zc^&Z;MyThxN5kKckf-{_IM>%mwPdNd1xY~!KLdM^olR%0R>mwkXWmls74ucP^@E?Oj6@^0qrciu4X&V9G#*)=^pWtN zPVm3F-E;k;=uBrF=(rwZzK}AG9&X)yPX3om@=~Rp&2P7BaFojQ{AsFZKou;ra7>v> z^2h33k7SNP$g7{{vU);54qmFWpOt>$d+dkum)Z3wh=a=9dI_J~{71zi?#{yNt-ixE znO0!@zONuHdlLJjUKg*3jeyh*K`mRw2H5%KutOq&^O7#IX`Gqtgjr{^0o7w}=vA|k zyO``0_*Enh%mU`6v^Pwl$Xdj$pPqC4eI`0_#od%Pr5$F+0&0lfeZWFpN?pW+ef(b^ z7%tkhg9`1Wf{c;g?vE(r*>`e$^|(L# zT)IeHU+hYEWDWT=Cqu<#mV< zk>uON8jAI`q#+{Aw<_U#vsZI1XASb9w!K0fIgNDhwW~jPR{@4TS`~5FpHJ~Pi7uvL z4rF}}*~b3B`j7+U%;65bDD={g7uC50*r&?J{4uB$MCigij#TY|Q ziFqmfOnNS~hIQpC=c;I19=5}lWZFjXB<5p|zl@#wIRo6sT`zsTfODCNRCaG8ieTB4 zzK=P$8t0@w+m=q42HTQd9d3&v7<;wtI7HG15oRnG_llOnY-;n$UhLx(`25GPzi|vM zrwJclct3)y6@K_va}RDe%C&;l z9PjNGJV^!~MPaTbAtDkw*!JB%rV9uo9Q?a~;^CTGPlfA^8T5r)Eb;*95GXu|^XIx9 z543x|&MPQ%Lkq=nd62>^(CKJ7JGCxXAM!J+Xkw_SYzXj*Zge_holF2&)Ma)yc&P}oLJa`1Y zpy!7Ki_f^5U30?(p5Nfvr6kJ`ge2zjeV|VXG6Li{2w-M1~^pVQ-MpyETJsADA`S?`c6| z65nK1eiQ)Y6wLAI6HrBcr|e|?911l|HTJ{n^SQPd)3cg>l(;2e^0|rtHFAR)hpclU zVoJ1!>}5H6V7m2(aBCV#JkDQYD9(YbH^xEfd-m}amk~s#>Rn9K&jIp|^zH81 z85sDg%tMLi-x1VDgk2tILjk+)_@>elM7F)v=gnV6qXiE30af_(5je`WJ=cq7uY?{< z{e;j6OPuZEW;#S)+wr}Dd7N$Pk>XF-im~rjy(Eeq&neip6onO+kTgw*Aip8@cV%S7s;JPXtSdEGL^jq1#u|3wIUuC6c4}fDkPv{ zvBevTIB`#O&(3@q&hK)WV~;aYoJCnZM|R06hoF1X>-~5`3@~4CJ>&JY4sNfP&)vPa zj?x^ddlK?u;N*Hp?hlR(w2Uh2lmPv3R0OC|Q#EVUqyujz4m zqfx*$cxL}STReYh8tC>X>xXQq;gCqSC~)|(sOgBY z?A>5C$yD?#>04XahU8TcDeh5KHT_w(a0q3yuSuZjJC zZ+V}yA9;mh9vGyD>`p?iS7oaJ4*|m6N4FTb>yf8xI_q!xG_)dfi_Rir6b2+Tlix3l zf#$tl-Clf7E;`#qRpxX;oyPNY!;hDs=jd#6c;qA^V@Q5>=4K}Zvp!v?Q16F4+9NrR z^aNB{LDbh0?SufAnekEl98YH%mdtGSpsbophpf;2564FIlsfGg^h6)KH~wV~1`d=R z|Kr*O>d)RBrpN10vd!1B1Fu8*$HNkjDVl)6;>~bz1kRhCH?t;}Y=QWvd;i=Ctp_X8 z;_Qo_SpVVfXLiwY4ykTU2*2~GffT+IH<__MI^En(pKB={C@G(7<+D`7;|2M-G#R{} z3!-!&r~?h$d1#d=Q3fBMb1rQ$&%*eA)^{<(E2wWfKKRFY33xa#JGH#5g8NBknU&Gg zAb$RDLO?axu>9bVcnzb|KG}2It3Czt;cjAKedOJ9j-o88N5DE3)ID zOc78;nfi{CkHayd-X^u$2omN#O!`nK4`P-%VnccQ5cePQj$7LVI959(&4%k4RH2A*S1g1nYLLF zn_d@>!1|{po)WcGxfw7YHe;d$f2yM*XHSuj7Coh^ZNEX2XD=Akm(@ZO_eZjA@e zXJ@X?4}Vw(1-@vhlV4g;$Hs{P^TAYjO24@OZYcKG<39AoHvN)#!idf)&PU^@gY1e-8F@shEviwlY6Nl?(A*w=G#)&b|R??&0{cVoyrMx&= ze^26ixbn<1b^<(ARd2j;q8_=O6FcTbnvTe*Jmw$fcEPEguVO8D9bQ}EnRD9iL0o-Q zesqeR@a1IC$=Oi?Oli>chZfJlb}To|z-|XnGzU*De#HDes#MttTxa_G8m?two&0cv ze6+7K5gvV!4}Cj_=fvHmLIi0%*B@hGGfi+pPvhu=u5?Tysi{Vf8U7{^zj$xTx^Msp z*2hcU?O#Krr+wK%xSD{>ow+Z(Vg}BKU){`m)C`N^UH-0j8-a;k<}mwHB6zWWT40gx zLagf* zljJpsQd;Dff7dkXNoZs`!juOj9h>Tmz0>Fd*M-n~VNGcN{F$`Qom`M?nS8cOSb%7f zJ(DZZ9T47IvcXI769(x%cBNpywCh&IS%1M&@EYD*SE%s=7)u;YnRhVvpIN+L_uC43 z_S&MaVImXQZvL6&x0pfe+WEt#^+Uil8sk}ta~KkXD~PX1`w{z5`OT&qJl|ZN zF~5oHH(i^XFV+*VzQy5g@7^5vlA)&N^R)-4pE!!LMa2S9uA`I@_tp5`czN6_Tt?L< z{-u8~M@_^xyq;pc7lqtr{`Ko;2~xO5dVH)S8lq&s=$;hA`L_PAN-GvHzg-~eQAf{rMnxGN=!6M0lN8vW2gcPkXX%H>(VcxMN0u>jd#m)*^9v$o$V08_#mn$3 z@L|}$@Wb}=Xk2nf&UVHI}$kg#kxIRpIlyzbfwm-Q^ejl$#0-w(_%?VAw^gcnJ z@e31BWs5Ihc-?MnQxB91_9CGhJR24hT~MWO7NLUkpqJW3BJQRV(a#C(UD51z7)ifT zRF89?4=KqVx=qyrF9Y2*aTvTBF;&z;7FS6Y&aJq># zs1qa;>D~B#Yf1h%MyhWJRNJNd6Na!J&NpZvUwQ@3DGYdL*-Zk;y(c&73*%s1=Ww^N z91%W#QF&VF)eUcIu4Y)&#$vyqtEBAN4!F(N2_Aioh_{4s+fO(aD2-%Caz9~ydSs!^ zy*K?}zTn1j_kIk%H!D^PQDdIQ_^+`K9!ntZGL(7uOf*yqy-;g$UO-CJ7k%}$+mXaz zj0mk>6gdA|Z~ys^T4IK~A`ia=fiS_IE>TZVm`&ei`OPo+a;y36IQGRx2l`WOO;4bL zuJ;zwa#Ij$Px+SaLIc`7?H_0VavU}UUey2W!a1HVzC|1^nt}QK=O24sX@JBzl>ruW z%zLJ>y``-(fEW&VL|6SPLo#bj?8Aq%aD5@u;k6%gqjF<|9+b=jTU_e{(JI{c|M&m< z&zF;1t(nN>X#)%&f33G+xycH@qo;;w#x{ZZ^ z-VP1h5|I16B$UBf0`3;yiygK5k+Qr#`J`V7;&coUtq~{&&0n%BX>C8icbd&|tZ@+i z`d;qCBv}BQ`)XWIo|;9Ru?H@HSZ_gmVhhER6uFS%oz^Z9gE{_7CcorZM-gY`WyV^O z97u?m8M*E3fz)Mfg_s`=gJykW0u6Nzyyc`iD9^G4+xI`R?*Gt-{%TE2Ex*eK6&Ztl zd8evC`TlO|*$J#ad%CJcw zUmq8DZGF#i)aU*ugIS$b(p%TnPwciMV)m`4c#`@EHGDZ~ZZyOs>7|aWbWA>@8&9WO z0uM|y2CD zbB(8Hs?IDM>0gi2Y$a`m?*oJ0abJiq*sRJwIk<$%X-v+q7&YPgn7iQEBLZ;cD2y(g zoCk%$+adEbO>jVnz9Qw$0C0#c7~DBdK&M4$AL29#U=>@XZr*4BY2HHf!OC=Kq0yzM zt*wO8^WKf|I4ALHczmSh5`k8INuX>*~gTQ;G20Q*w*w~5BvVjn`;nPDxf zEbuzE&%5>@&eKY%I~4Sw1A?Zigzt^xexa?7s0-$E`42`^8Bh(QCi3Usb5rsDs~6g% zSHA#Cy=C$DjF&*l$-CvdNIE!V>ys=v5;51Kd4iv*2NY^EY+m{$K|#&T=A{F5D46lo zV0zOuVs&&@wLO;rOy(??Zhl*V|53xn+D<@ajkFy1ZakdQTpQMmTgSQ1)tAvsD-uob zXJo>CM0R(YmU8!Xc=%fI%hcZiAo-?R(8d=7zYf^H>i^P>xVY6)uUfCdoXo;GzN0a4 zv*CN5Ne2PhaK0|Nx-|my4=&!2kBP>)XPdVR@3(_<*whVw##ZD~MjnvX8U-aw=kxxk zFCvBJJAu^L7nbR?T_zzH32hO-7Zc5UQCqAU^D6v8GL?%3aLO5Jw-Gtc0X=MK6D@Q@hBFc@Cykt-n4u#h?b0dcXP=P^DvZOF3EiyxG=l~kPVAomk)sDy3RMX(eUAGG7vl%SuCVV)BjXg9>RC(n7>j#afRbrZb3FlRd|Na<8Zn2$44!kI)yDk?+V5&oQJBvwz3mwHtP2e^&-3-1Edbl4 zm5g=U8AST06j(-@(C}GtrhP{W;LxXiw}&{#!01n=l6;0TCmwG^c?$Vzf51bUcC;-=~Qf1@)uE%@Z=ATuQ~AP%uy2>0@>tMQtZVopOe+|R{XE^hS<-l)BH0q=Rco1saE^T8 zq<~ELoExQO7P1Hf+XHV|H1K>oVzpFvED01#%qi+0uHzgI<7Yo-`e3s>uz|@w2|n?m z6fUt| z`!uZcS&4~Hy0e6i8X5K^7GNLS(Ii>TGm-FNyHv4kr2`p_U-%o(`Peg+NhV=|?ao>-)5Ld2xXY2RMD{G9ZssrZUn9)~muQ!_wLtoQ3| zTmb8gD+Jz`m2g1I<++Ay9SmNxTl;$g>vSXUFwp(30FLRd>Ky@m&PNMXR+eXj=+}>G zavc@0c#YU~>dY8QVAH7{o1H@~%pQ?*6QwYEl(7FQp13Z4s&Q*+T0teu;>cF01QJJu zZ61X7qgHNJTdNiVoEGGoni)m#Sg+3aHtwgMnYv6H^tKb(YjwAH6N_P+;)=i;-8kg( z?KjoS96?&cwcVFK6oVmd&pdLfLx+Ft&VI!?UUm1k{O0BhKzD7+D{TzV?QXO7343+I zv6fqk`y&cKcy~J2Gs)4zV7CLTayDk>hfqJ{4~U%v(k2soYry;S5HaRg!*iKA!}ahLYg?=48j7 znnlD%95Jt*#y-4HtCjtF2{4f5&sK{$hcay&*Bcau5ZOD;rms`+KrXDHRGH8NDPFZN z|HRBfzS3t+(`#}6_xaI?UU4XTigN-qC7pE-V_(1%6`WkzJR7QA7sjpueJ!{01?=SAQq&saFq*6p(rO5p%!j{LSfm*<#@6=C0Ab zxJ4*9r5@)^Sb_=^7aNow1@7`Gl@@rNpKfM&bO5jOizc7!H4>sAXkJwRbu+FP1gmUc zdbXg$GbreUMihMTe%utmI{?j(+GUCc%i-;2Xi9Zp1pJftlKj`#I2)VoW^kkqloQmA zeYWu2A%TJ|$e2^ootV}Vgv`+K!sZCoepjF;5w+As%#u8mdwaA_ze5=zaUS=kCV@WU z&W3u&6ii2iI{Z*=L_z#5=FdIxT*>L$=P#H$SLplXfeg(OsPs(5U&nKzte@n(IrUAk@)6)Ka!}%@AzY<0$TfkKDAjR91dXQ89T_kXQ z5ERNPuZ5o^ptBSDgI8E;Ak}otI02ulX1a!|Tn(7p%CmRS4C^YjeO&(>q>e-fbliH* z?o1-V)Pf1RYt>Nw=)&Sf(_u`{m-ci~%z$FQiX|`YA_)54 zEHbC80+tFLii>?_|ZmNvieK7W*7zUcP#t z&QyR-s_tuIA}xZGAEN!^y&GZw#MANI!$0Bay75E7;sRLjyPXzfI)f@2FXj*f8&L#* zeyQ%Ce30ulKVrUT9KG*6PHxRQk2aW>gk7rgK|%SqRT2LHx*ang-(E`q>s_v(#nbt~ zEV@cLbz&SS%nuV4m`4%4{9$2&OfG!2X*i(%br$^dqbn@RRuHL}aljja9JsJuMtxtk z51zZ2-cqM8fqjQ+Wp?{AVAEmZ^I7?I$bZ6cgx zHmv9EQTUkY+l>9v%!1?O21{sojNDjUpdS+AT<`ZiNrVtPt`~nW=e#PQZBDd7~R1lw>5aQyo0VZE`x%9MP^=A1d#u$d;h!N?tQPy+jY1O zzE&Qyxrp;+EyH?#9{bKNsk-J*z;LR zYZ2$p(sVG{B`iQK%UU3}ZUeeOyZflDdK~(ubz3Y2MfP+G5{TXLIguh;4>N%Wf2SP%0Zu2Z%kSDFNU%r|G_43nAFog_-O!yvv^G`U zp2fv@ev#CFAJ6Bi12bqSGqFBd^r*4S(_)ayWo06$%)*IdYEdsXSJ3v}RPn6PBJi$Y zzxvb==h7&%tH%6U06S?uwKu;ohx*!Gt7^=vDqlZ+M1ye@DZM+eM)x-lWEmw=t3DCX zHIFGDz1ex>f4)I(Y&RG5d(V89jUI$c^whWP%~sLjt($JQHFDrpXXdk4SFx_sZ}HaI z-`IE9^>)lB+ipL z9$B3UzZulgtrI5Mn+m57 zKH}hN?MJdVmWeFgSbszxIIVCYE_`Ys>pXj>R8 zeRYuF!nV$n`RXNVVD~lKCYyv|*=;4VD>zS~gIcnFp${DMe@ms*j3AANKIvh09k6U< zaMiL6=f++w_7$)k1G8u9t#pCypy{*Csl&Yl9=y%(Jq&sgac-6=m9HHbt-_v(caH#Z zh%4$P5%UWI)2QRph|o)Wn)HgvH0*8Vq)cmShG6uu)d$y+OC!QZg(kkBF8bvwn4*AG zTu;ry0``OHD>1p_eU&uM^1B~%Cz@j4e7D|L1ztnD1bfVDr#F4Ex}!Uf?u*1y`}Et&%7B84>GOWEX<&@79_7aV>(^_IC(ht`J8_>nKp<@t_Qgs% zR+O%yh*X|z9_-syKP#m@ihUiA|7Iyt{BFbfpJtA42Xf#|fpg%!{i9gtE+p|t^C$Yz zm-gw7Ru(9E=6I6ed*ko3-Yb)oOGqF?D{IU%6Ie&a8^krMVf#?J$@10|FkP}f?Xi*p z4zx}`e#qdw#^c&jCjI$fe9zVE$?r7a`x?;VWjl?c%%f!EIh&B}6JbM|)HGOh_^{k) zF#unjsk{~+tfApyQTc?7WO&cEH^HEA5iLE;NVu2M15%FHulr6V!Lahi9o++CFy?eF zpu3|MG;*q&RY?-T5J$^+*5dWzIhm2%zzD3wTd@BaOaNYfZm~Rz6r>kz|0@0P8j@n1 zY1*lehpQrPoJYE=&^JC|`&r6q?7Q)fjDH&ks>7AJ8BdmA@BWjIkBwm6?t4t!?-R?yGm{Go07L93|?ScW1x# zp+ZiDTjt9%sJtPB_2s8%Xf3y(F2uV2;?4IaBMVE&TA1v;g-R5x(UbE=Gvxs7?CIgs zwQi_ilyU9C{u9c7^M~!<{Ha`HqzUn?hb{8Kh`PKnlxJwKBQMHDU?~5jC0AyL>?7R8 zX7vrxcNIPR!GkP>QO8#%4?JHYYQ-2M*Nq9_)UR_gk{E+mn#diQ*P{S3CQFCFF&K3@ z_tIK(82e+dteT$*2U>|3BT&3H$e} zpq{|T6~VrYu1Gyo?ozIYcjA(^-tHe!W%?Pyah6H+BkWid$!(l(o-nTa74J*KZa!QL z{VT}+>cMoSz;amRvGS+2!v5xh-~|TpTwuIfNStFUhkUk$+FGhngf%R2LgMqt#f@-h zj;tIi6${)OuwE@>?AY5IcRG=0s@QA})`zne8}K|`o&sLs-8a$(3m|py%!=Jh1cN_$ z#=aIbAn&=NzN7x>h^%0h4k>n8N>UXa_< zJvp#WZ_>%ww1`F|_gP#{?}f|poAGlGlcDf?$xTmOhaF`NMf&)>dAn0BQ)@L56u1Y6 z84IS6pqgtEL&*Z-uvhbbWs`vU5p|b!sru2<+3Tu@aBlO1bBrmuMtDD5Zale&IT5-S zqk1Ns77;^%Fo%m*9C#LfNgQCvLOp6Ta=9s8NHz2n%khL*@KKguw<-LJ1UuiIbHTdH z#@W(_&!y2o^Mw%AlZ*Lkw9aim;sz04-p@kIplCQ{Xe%K|vkK4F*BNBAmLdDek?v-! z>s*cyJD!Tyi>~%xgvro;h;6>!I8z!0eG5P0EDqw_v*Z0bydg_SaNcB#L?jCK{hKFK z{|clZdXnSl@jNMPka;(-F^0+|jnq&i7vW&<%an4fXNXUb;^Ste1X|*uHPt0yBb@Jl;^f9=yiWB(y$D4@lavp# zai%)OeF}3h1*~uRi1xs-zR4#M`>>wGL%#D5doS`bwx(s*z`4?m?qB5>M{u8fw{lf$ z9u%0gjeSGfz+gdwE{O!!6>f3tiTZ_oYFVCn8O4q8{q(FFh3+&oRUO=?_LvBSXCjkH z1r0F#OH1PT{3vt|%P*%3tf3DoyZkbLY9MwfX{{CO!)~;#$#RY?p@RysU)_|eK>qGI z2T`|0NbmD_dkyQtSAQf4`dumq`HwEFe0ZN5nsHV08qbBbl-eZL&N3hw86^+;DD+wDxE8ev42x_f23I=K z-g@hgapXA9w9;q04|8OXZJjz=ST~IPMCZ-FDCdKpwo#djY#+L`BlUTE0_!ZIE`*Oq zs*awMgwZZ_AV+t?TBSnwOGcx$yId_CP&i%zu7~;>t8y z<1AoD8%c0m^CB@lryDZ2%7j9{V!sZ*>lmk1A`HDSrDjkFKs;=XrEG(1?P&uDlf!oWg^w)k)U|yV+?N7yMp!zrNum0N~Sl)kK z4IZ;Y+DoB+=b0?PhghO0eUy_R!&Uk@oEzu6UJkqK@MjENxlKG(9CV0q<7=Y1hI0dY zd}NwtcyJ85HYzMGdkn#cP>;O_hILS?&bfnjQ#c3xas8qsM;G`Q>r*RH;qjWbb6H#hYDsaj1Nxe+AGzS%lH_8;Q{Rux1GV_7Q3b9aqPt)7eDQp!zaYe$M(jZn2DU7c zC)#1?n7i*;JDlS)FL-Jb^CmuUa=MHiZ-sW#A(j_6rh%ZuvA`YB1l}PHA6D~PfL~rL z={t`T`o_yRLPIu*rnkfgEcF|Kj$iO=gTVk~2TZN~ksm=jF8jqY>9L-BbUI^28grd$ zKLxy#%mkg(LnHg{)MD<2$MlM)~C}l3cCuC$8m7hGb=e2JE#L@gX z%_21oPyWs_Kg0JcKlR`o7MznxpP&%Con3_<57wG6wPL@(5sl2*%lW|OoOen9+s|3hV>`Q~uL+b$NrZ>N+`U&E$g z%8zWG9_IvXJkYaJJJJoowV~8X*pK4f?=gPlQaX%VQSzlOb|e1v!OhBceDAtTdp%?~ z4fief`3GZP9-X7ZrYj~2_hyRJ1mOGC;pi#hh2|aqxyPUm$wH3W?>Za_XAj05A zVK0>#&hhf)+g=RW01@8p%U(*Ys4h4mVdZHoWJcK}OxN`ybE=5K(W(*P*ESTDP>O=K zuEMwWE+Z(PJDRags0xW`9xdN<73Yfln^$@N_7lrBE`q{_9ST~IO&!vF4T*l+zc0EU zCA^_?y7xi29(-y)HHWc`qXOmx-@jiE5Y91B_?3FsqkZ32{fmEKo(&zlP1F89c(XOZ z&5iTr!l(8f*_S>6mYj-Nw`)70;C6x8LzPkR*l!}iFt~~~mH1O*@cwYi`)N5#aU;rP zPRaj*{R~|(Y3S#@Hk|ii8Ek_0Q&G}JeQr@AB-h+|YdO;dy2_fRC4-nNlTjo&wKWIS zp?-}`*vFst+(vWED-x-io#z_9I*Fdz%(T4DZ3N5xS8deDab62dJQi{+oGw3K_j+6)0)3=>onNHNQ5v@(bT{>bW!+b(JcCH#@X(krmf#AK0yt zI`$wZM&XBpmnuM6wYxg}$TZ^huG_oHLPVUw;&FOWWuVb9d}b2+1k+P1xbTFw623pd}9JgbWw1>yHpK5CR} zDB?rUuHdvbv8zce3HSU%?#knc;RDWh>^)zq-hMY6(QoTx~lx(}Nnf;3io-5su#cJi{bN`o+aI^UN*e_ zrKs+9v>Zw(6!V*L9Y5Id_mqiKJBad~nfcs;>s1wsmM_I;AR)>$Pi|oon&y4{4OTO9)+IBwUX24uA-TY*iUi|$&kOZt*UaP7F|}?&^<6Ug;Kwi zAc4#zIGL!yd+Rq5=B|D{V%fEh!n86ThX*G?goe{{|D`3ARem|}F$ zalOk()r!P07Cs4_yB)9%c%@H6pJ=Di z;l+7ZwEyNw_`mgDN!YyMgs~~&%Xix$hDxHG*>fgy8Al1vQw;tZ|PNLX8CtR zbY<+F+jxJZZ1ntbXnhq)P~IPY$=?Nf-;yaWaxLMy@#V9{xSsL!U_dJ)cL!J$CTSeP z=c}&*y9r%%^B`S$Q%LD@8whcnHI1Z zGFNB@89&aWq$Tyxv%|A@jfV)K9a#(4+;c&=?Y8y|OC7XDy$zkDZ$e8ar3JTZ(@{bB z#XDqstD)=y67t$vgod1%5a#$c@E}pX&EHZ5J|DWW&aO-$&yes5dn+O;xhP*U@S+O9 zDEi*fO6=QaOg2u#^UW`S;^K{}N-)(671rm*d6W*JcigHMfTjN;+2xO=aAQG_zvA60 zOrM?qy-&6ik?svWu=h)Iiz_ctE3;?hoj2; zG3V;?H7(iFoI((fExRCks17D>gcO$j#5pphM-N+l%maoy=~qQNy3rDA3x!;2337c` zHld6;NkjMismIIv5PiIKw*w32E3($ke7l8nOqs*ti*OEWU=nlPxgV2Ao6PkP>kFK# zw3VnV>5c1PgJO;Sj(yNf(UlTJkqG^>^_+2i>o6BT&GR5&1$2j3o%Z^~1Bv#XCr7ty z;L>U7(WATT=u+^KkQa&r8Hbyy+2I*zS36C{EPn;HKgEa)zc}cXXUJK{T-4o{!3$-c zSl@d>G}$jS7Si-{6RNeBKr)mxQZjuR>8M7&G9|{q{(s~3KQ8A?r+=b@fDy7eeqh{D z*bx@ert=RB@en|8A0s&07#-iSVQ z2)a87wi^M^Fk6py=njb7aU26fjWw-=tv=XCv)EnfF#_ZtN3INZ%)z|QX9^{pYc<++ z-_B+Z>mpaFgATW@B3I*n?h1u==;p~K%_yG+X(>kOQLNvSbUOWqQn(!)nZMO{z%5!u0q)TxNJ77(U1N(d^*YTVg%|c zNGgQWvZ1Txuz}?27+g7Dts{kb@cqmhvHfb9@TTLg=O(_tJbb=rrnxZ%virJuJ3`Ze zQz^`Dr)?Bf6}~_8@berhcxQdD<6bH>Ur{!QHpl&A@tLK-gd#*Csgg`#nhdKBNw#eY zIcQQ`AIjCcQDlSe=uNp~2xs({?Q>ZLk3!a?Nr|1P^KGf_+;$=;)#MON0^`x*gBAZD z2iA~ewFKeD=Xl)T{=Xl>zxDFGkBHfpj6M3fg9}3JW^m+~tjqHeK0;x{V#_@toR@K8 zsI7Dz=iC@K4p+{y5+w642&EQ&MC<*RZWrUc?MkyfR;@1=@w)LlLUXPj9V;-@x|lSE z^_pSgxbF`{nI?|S%xN(Gc0*PI^VyH`s(cUFZG$$AvexrSO>pb?#zc8cHpp%wu6VOn z@Rl1ElVBeO>cceR=9mY^EM_I6b%O{$1yW;f42?q11!LCT>Q&U>ZIh;aq6R`n^-21D zR^g-KvwgdLOUUueZGl>YYT&-|^kA_~AUb>hnsqtm`uZ&-Z`(>$!<#|56dBo1kCf32%4)244X!EtyXuwg*PK}F)r62&nhrXf3Y)#ecFAxuf}&f*O1Z! zD(^Y^DzN5vFwoq;1WGX~ftB@OvB z@ab8nv;AIxXK`%3A);8f+|Qj?-_wg~+ue`(B%K22S3NYZIB8QR_s%$}l8MD8RHw4Q##I@)83d!IZ_1p0sD z=|9fvO-9$7ALdQrT1R*(EvGK3ns;~8(B>z2xO`H9QA0uX{i8KO@3}mG9cdECXOYVMW3b zGlG;2Y(c#O_aA~&AO4kGg4VxFys;#`$o;|QvUhn6(9bAZUH^!A>Z>l`wX}pt4=@cS zzN!K1%*2dy-*9fX|Ka%>(`F=pesN3lOF6uJ-!E$1(22xTj#6~1<|AkMzgz=;WstFX zc`^155r)}xJk0WQ;a-xI3YU2q{L=YwGXVRMzg&Og;)eUj2T!Q^_hY?cEX!Jp$>bso z7mf`i;Q8^eCD!QAOes)D7DXrZ^g`WV(%bx4XZ?(sQGOTuHLC`4%Wnn*A)lXei(`s- zd}ml1&R~D^JC;n&Vmu#)j6y7%%G;4gU5;hDNe+ZuRMS1>Fay!%38YN>R#Am&uAmL( zha{gU`>Z=si*vtin4cb;26mSewHW_waBZm|e90N62h8qQk|uC|3^l*T84Y~C(j;#QA-Z6G=y8WL$0D0S`_-Ix zg>4;_U%m5l?bZ_J-jh=?F!mw$la|j^Z&X8H)pjl4g_{4DkD8I!GX?D}b5})a%Al0- z(uDmRA0$z86%iyRQMItBv8o;3XKu0uoF{gncMF8O=GH~%Nteu37O7H*fBL8P0@)JS zaedMwGiw9qKfK`#n6nsl=l6M# zl76C`#Dz5-vV$oL%_+e6Zyfx`g}rv!Az!l26v`!ej*QHjf^&MHhy~wqLid>9X;!y- z7~mxO>oScaapce*WPN~Ok$3n3oWgwZ`wP^Q%D4}f!F6K#$}ecVZ|1j3X@cCPy(EJ? zCm>$(JF0&$04iq!3hAS9U6a@Eh6(1m&iqo#PvdEUdFuLvtJKr56|MMUQGf_^bKFaT zJ58XI^_WC=rWd#zv!A#ok07PblqytT0n+-rXAVJ4OX-=chV%7G;yx-9Yb-|a;_d^U|qXA$JD`{bF7ze581 zI;zbCCsDyEk(BzH63jUtZPldeL0&h)t50HZ)%3tk+ERxC_`qab^xJV7NeGz~3n@3E z4TI&%5X{rDkdH9U;hKipuw|FZ;RRq*N^G&*$%BE^P*XAUE^yxMi4<2a0salT!r!^s z@Ei!kNBdU6Eo@U>pKlo{v9*wKzRkutBqwfGDXzkvXtHjTyiUaHUv_WY0_TVA^_EFc z?}1JJ^3C7LYv{goMwHZeIxzkF{(}DTdgcdzJ@?Kt1u|i!5MhOTNS}oxi|&C4;kM3k z&3Vl8Cf?Wn=D%kg=?s)_2;Ze4#eL|d#fv= z@TBv73m?d{= z9xnPh@*82lXZ?1Aeav7rgm&_BBs<_-7c!aRO`d8f9!ShjXFsa~hNjGxZ|cdec=~(h|rkmC2Q2$9Z=R zj~}OCzSzQbUNv2O-?1oVVpqS?gEV+VJ<-+ zLqJp`*3S;z@eAUe#~coYOP3=nfbi!gogYUp)HI4Un|PK%U2|&y7uLcP4H9hso~VYG zxe9KhxX;tz!kn-nj5*eg1*4QTT4+(8ba@Wvs(dQ)dnKn)3eE>pZc7ODg2Qs4*8}-A zL|!bg=!*Bbg+K9s1$O#iqUx#m>o-5q_Qgdu(cT<*5oT{gvkf2&9)kmAMN+~-pk{lpm$@jth@^b1Ji@nu_#p#DIv6MpvkE%tLUL%r<*gru+9dBJ@Snv>ir{7@=aeIWMjC>@4Jc-SpVm9=;+R2pg3lYzF@DbzmEshaOY~0)d~_; zLnJRO3Adpg`#SP3=?O^rR!rjc-U>*0#_pE?s||j)r83X`$$<&I&9VE+n8SAF91rWG zHaI=5qqy<05b2oHn%uja1v+~ZDibub;CsYO;_>w%ILtFovr3zWeS-h@)BW$2aZ7sa z+pZxZUg{t@)1r*|)huKz6oQ1r7wX2-?JdwYR_f!9KhWc+N=dOO(%s&%PcpGoQlIn9gm1(tttq zxp+&&|4kOOg!bGr|C)6ZQGr$JR5-x5a)_L&r1DhQMv!nwl}%_uqr*#AA>fAeDVeiv&{^DESA zak2gQkvFhP7n@4AD?ms;id?x(TY;8Y&&{R$B|Q9gGa>!l04!YCc{w`VirR?jhH_4^ zz}whLnPga&7df#8&XgG9T9%js=m<5GV~ThQt5! zzA1bb_8pIXi5eR!9g<8g!qBANDJ8{30B=tROSS|3i7;OcG;e4>?I_LRkY9a1>hh9Y#w-K)fi6!-VZ*D(9<+sn|?tB*_xYK1??IEuO z1@^~=+iXP0sv{;%-S2`x<@CzlhDxMb5c5~SpNQ^xQZLfW5#euX<7o65BJ!J0apCrA z0Odz^veSlj!1eF{{P%r(E=gK$t~`W&3p288TzcqAG{HXEMu;#$bL*L#SUFG=iSmm{LC*yj~oiS^KO+T_mj z;!+4mUW^>^Ye8uZukBrL{6zhnvEP_f(}4Sbp2Nk)=f>%0Z&0PK{rdb@D+m^)njgy* zA{_G7%ynBRLq*3~gsWe-Anj{puM_KW?ijUOoI-UO{JER`)kT#E>_!*=*04_l33Cyj zh*Ad(@AG+Qx;23L&!1#HTXTVsapZ%>sTTCLOy^|Xz%Y^w2P&UbtS|WY9RJNv`-<6- zi1Rk6Ls4j3KK&_L7=4o~<|ss18rAx!aHj}J&VFb$z1{)})GmJt_pX4;>0O&GC_~TN z^_w<$ThPjgK_fHMG7NLgzRxOYL3DkB8MpCzq~*sVW9ys;rGJ^&_pr6XgO@a&;UPm{ znHpA=TAu|R7vD%ISqwsO=+>4!bt&4ZNbT6PO@pKV^L%bY4534IZ_pL1tDQZz`pD#h zao;VoHFPI2cG|VKGjUlqh}hG(aCSugnf)HAzpT(c3kN=VPH7U_S*=8 z*q^grjJQt}u{TMcy>=98v?m!{j#MI^J-6AK&Jj_I9{N$u)ekeB%0C!bo&zUmmzend zb`+zY&~q`X5Vrj59t3?Ggg{SsT5E}7^yu78>mx5SVD0aw_<5cT^iG<8qJ(4(X&?OY zZBYaB1phtXf8%}p@~0UupEu}0tNVKjIzyzWKhr+EUxc6#mu*D*sQ^j0Exh$nYk`|& zZ(sk!xiLmEw?Dl4mIF#>t;V`8x1oaMvnri4LO155(Vb(GI%^c zQUE8m=L{Kqv2Qntxz?$94EP44PY>Q{0P>3`HCp8`$F7jM%1*Bg_76DsiRk=5nm0a% z+&TXfzUUL_ujJ$a|NlHk4&PTf%LOBJs6Dj(b+{>-Okr3|I3-MQrC}e-3d@Ju!ZXZ& z54Ixj1KAFasWXs!mtlM~IUm({kkcocV4iR09{$Oj_+C3lJHpD?2re}-dXf{vNY}XN z%L9rMSk);!U8GWn$b%#od$&g5nniu{F~KYl_@C!^dvJAM>Zlw_c}Kphedale)8-Q= zToEK(?K~gd$exEJS>?|tQMJQ2-CsU4nLoiUVV>-xPyw794?6oGwFN0kSQC3pyJ6>u z1nVz+pD45yalD0jqa@0+ahFmse^e)u-|1`vs^yIkv9B71{Yz@cx&pBu_1|;+S7(hs zvwzi}=@GC;++EnZYYwle&sE$Q;U&!2A69uRT@TDnEtMIs#!%mGQp&A&f8a#@>9p)~ zmh}S=W$dpIe68TI;Fbnd=QWboo=pOi z+v&lfpYw2Iz1`i+Jq`Qb55{WBW6Ps0$KBPu|$b zdV*^DQOVczM+tsqC(f^79~YCA)A{>27n4O)y_dU(oRIQCQ*UCi9;Iy`4JGD`LEnt; zw7f0}AujO@rXn9HzC*E=yS2@6~J(WMJnTZ4;VLD|ICUi zh0xqB+ESMaxaWcxnNt>FJbiSQRG}A{PRCX5zfunE7Nmbguy2N?zQ;I<`t}vIyls6&H_x5OX#Zr!kx&&+UeI=Gn+*tXI5}=R6R#o{8dr zUFW%O+JzRjs%D35GvKCk*|v-j&Xc4tvtFeb0XhK>U2f?#=o@%0Dqe=~$!417A)9lM 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

=hGF@zDf?i*1@yt!CX$-4ObLvzN1Ux2%>y=@ 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

LTc_XT3x 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

j&H+8?3 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

B7AOf0Nl|P=>!E6v8uI`4Tl5=k7#8{@r}$ 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%0ApLgM;FIns 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�cjn7V_*VD4oj&;M5hN!X!X(15CFPf5C<-$cn59{QUZRnpqMXI=K6LjPq zT;UBM77UY*E2E)O@OHVl6EVB>wX`u>a5J z;II5#A0>+os%L%vUO3=0GPcw{`G@3+R1m?R<*k%jP`C0*V>mm8ntb#Qe&0DE_4;e@}E9nL2B5%M%E)V2-&cy9*fd>Vo2 zW8-|?RC6$N<_|w@Fz%zr>qj7J6@F}L*_7T}LWQEf)8@R*U^{$Nig&a=TR z>`%UKW2xKLgVG354)yIKblD}TM6sa|&bt5m;;DyqWN#I!?)KNAC-PVPboBB2VyS5m z8=s;J=G5>T`Y(ILV)*Nr{wS2IoKA>~`C#oJpYuy?j+ zOzm(ldY}Bgm)4*FML7z-vL?<0Pwrh~`od|{{Uwa@Pg*?+vL<=_KmNLAo0089%GjsC zT~YLq3Ufi%48*4~KLq~s`|1DZ=ZuW-(_9B-xYfRxd%WN|6qkO;2szFrrIElQ<9VnK z2q^UgXBI|L&&l5+hmQOO&S~b`okq1NW%;YRB;z<-DIe%&+)oE40geon{ArvUwp!v_ z(Tsn8$41STbddVb-}AqDkE}<2e9_fB2V7|dft@5`s9wgRM?Cndl=Oc+FMBm6l#Tf| zs=D+v+BNGU6kRr|jt;sib^X7d7eJ&_J+CE)PCh&J+b&uehL_^r%6VUvx_v`Y{{Q=G z{r~?YAoySIDPR0P1(|;hqMACV+;nanpKJV-k4_Ls1)h2o&O`J774He$T@F)2YWl~r zgc-M>H$3H&*0UOLc>nB_OUW2|Qpp&@dKB|aMb=LIZL5Mr!E*X$|74guCe8eqsT=MD z>VNXv?Lq84I_HIOe$(&Gs)eebUBEVW_p3MV3yuao)1_-_N82J-H0%r7;H9D1sT%kV z%8#sfh>uR<94N~)HU4JUAC;a^he2RH)Mlz6Gmp0a_#KiHuZ3KxFsH>)oZqq;ij(>FImLz*J2< zTFcoB@=WQK_W0F(0uogY#~`p+c68S48-Za`jp{eg=inBL;FD3ZLhL`0lKCe%14MW9 zcucSLVLq{4(gWQBxarYhAVl7V?xd&^EH5-dr|>h4UorXcV*4ZQ#beW`QIl=5x49+XgR!22yf7e25#N@jnb($(=QpGI`SuK;Q+hgo68oT|W33ssb=#n1 zt=gCz?|IIrh$?AQtb#&D?sW_OPN)kWt0&k`1N&~`$1Gw?z|D0mRY!ISJeq3>=NnRi z*ZEYk%xVTSF;w}Cd33>%z9&B=ex`s8KY`3(Qa%v=)M8ZQ>p)M*-Dq_7lYniajrjPv z2;^{j&zh=d1w~LBUk#H?f`|JCfz+G5z$bh2SuO$gVbeWZ>*R|EIjxN+*X@T8i*4|x z7|Af2j*a|&EhrBB?F@g+|JZ;pzA^RFnk{HZq&BHXEEejnjj5{V4!~qV+fbb>o`dVe zdtAK|3$|(dUBge;;m#I&aPrS_q)~I(-%>3GVk2lS^&eh=??NIbqIV|Y{&Y?BiR5T# z>n@@UbHMokoUW8wG+00V_22R6&(T1ssim=Ws25UAq^UGYXW;F$=n*oAhRDG$n?~xZ z&`h%=?mCI{s)ueGl-!R3zt^u^3ow_$q4TZfsVK~o0+s`5%}9{+XK=Q`x(?$PN*B~g zS73u-`;;6P)}Qf*k~ED>0J8^`+3VFi|}F7Lb0P4b!VF2zOYRGhRD zcX|Z)ygnaSU5B}V+g~1t^sE5$Fonm@Ld;9pz4XEAO$L1XyLy2>WeK%z@7HB3hr^j{ z-|6VcC7^lv@;NKc4|r8y#JshQ`-Lm<_m8g)AgL2^v63I=fL-cnM|*G>WKx^$Jor40 zqFCsIRqqUe+HEIFg6&Yy<`}%?8ovQ?#|(cj&-TE*hXvGf<#-?RE|~4H%{;hS_NRiR6p%9$w?|INMf_k+(PDj6*Lt5d*8gH;}`l+S8hVHo`XyGNI{rk8Yxhy+X z^gauPy)$CPeMIYUmi~$}S=SV_Q0aAcXote0aHh>b>pWUtP25$MpMwNXDro^m%n>RM zs(y7e9(-J5Ni}djhr8}ftSIhZxX!z>bYot&UsQw5m|YGm+>w#x#Jq&{UdgF0t9eA( z(ig~@Fp4sTFC7%&{fy`p4^?lH67<|`p@7snRCOuT7#5#@_DW~NQ zdj`UXq+9%_59VOD{g9;1`*c*&?RmvLDgaJ@3{Dd9!TCSr#aHfPE>W=fAB#_Un2Y!7 zt+I#aI5HyN^k=8SIYpx1EfpU7L)NOmTv7+-;gyqK?;TqP))l&uib6jqmix6d@N@{0 zw(oF!3dTA>&${l=yMFNgQ7K#b$vLRrqh>@zn0HJ;tg@xz3->;^3%#aYh75&cdo#Gd zQ+m0+YoqQ98#cw;(^~B)2G(-ME{`ID?ddb6IX>`jr?x=xlpnfyEt2&95#0ZFJ_$Z1 zgZDH4scZjRpHg}EW&|X0ZiGJl{agtLy)!B0YWcsgc63cw#XNbW6|6qm zTc2JXgfE7gk?u_MC?-$2?gDEo>~L!sFF&e~Eos3KPD_jqGq<vvr9l7&xOmU61yug zulJzQ$ee0tZNyhUe-_4j(GC0qHAj{iXMyJ5uCEj34E;<_Y;UZeM$*rJdcbTWT6Gi<(eW*W*HQW! zBa4f0ykV<@BCHp2Q$9|ev@C>SqLs-innEO`CrcCay&K&LRf+$6yb!EtxNrGl{X^p6 zqa-VAJurB?uQ66HA0#wgE1XhCflR|aUGv!xY8A+(5#-MY)|!h7l!v>a%DI7cp0pTt zl0|O|;rmvI=5g_u(j53mG(oz{gXcIDbKZZCWB-n;m*{?h8M-)UTv&|veQaD^TtZRV z@UJ~#Z;l$*SEV0rr~MkiMn>quwddK;%7%_S5X5}C&QBI*YY9x8rqV8c$%Lp&8EsiZ)gY>;FZV8f3ff~h zs@=b&<2_h!&ndj8vZq$PqjYfrycZ5E?c~!T$cb2o4)fHS{YZSChqb|49{;E$_JJiA zGp7^s&R~5lHLndrKRU-RdH0593jF1=ZaC{O0ozxnf$di?px<4+Hrj+JgG^jCmaoF>9LRfPL3k; z6Sd|muZLll_iO+=Pb3V+{oxg0!CGWB&nSBLJ`(6x~8CXXPgCDLE*@eN87^^l<+_wonxRdt>u0q?~OL;K^Q@H6A5r6J~C-s=(H;KaEtw<=%f?Gc9plNJyA z+1U~FV$b0fukr?({)bXaZ)>9_85a+bwR1}gF%@5N9uPcDi~<=U6B#KPZS!? zsZQRkgOOsRq$iZYz;$Q$vmM1c&@*VpTZerC;oPJN$DklEx*7N>i*p{V;`+?4NM#{9 zrzTwi=^#9(sBuw$it|i^v@6IX$AIYEs`Z9nAf&Au?GafIKo`&Z*jlPJpbUKuviyOd z3;OV{rX3yQi|gSLTtz=WPZMoy2fz=XFgDr9d60?Sytie%1`9JZ*{Y@iP|U%yW%9TO zzRNa*eCb<5-Jfk_zB2|u-So_*q|-}iP~at+#hj|!Hn+-R&IJIojD0-8P!;wuyM)Rl zO`(9m@goNG{_yaAbZB$i1`GsTWBR(=56}88)p)!3L6qR3`&3!uAV6N8aAOGjgp&V! z45aacvfoBOR>x=HqdYIU_k$IbMSczoo%~?Fz55n7_U}DX>1GwwUxI-J()~kozVJ_e zkBA{`5EhPZ??(&{g5cpZyQ>nu*k6#Z(v3Mp@7DdliC`b$#HRSP{TW~A&C2=hB|HwU z0@DS4&8sM6#`NOmAz$!y?KOJ-cL-fezp+GnAM^ir39ocvKghcR@08=l>%hNVB6EBd z&krgWd1i1v-ID+K&Cg#jU%jr<(a5C+&CY+kno{Bg8LBkQw^EnTp;H!;>U?9!Ojsx7(~Mr-$WN)2YDOU@lk z>;Y+s&S?8=HMnX~k5AzGRG#iU%Ox@m=hEcRH>Dx4O1lz}gZIw&h^S{v)*3){c-lbT z5c{U>FTLbt=|EGjYyGFyY9VA~M)NjFBb;edAWarZ14@OZY?|l_SjoGUwN1MOI``~N zU;pSqT(9)^4~LWj%Wzw|RbUIwp_sdS#eD@gBux{p9L|aloBO(te zUR0hdhT@&%z|qxd6jH|98^qU$#sn%#_lt_bCC8BXF!oV$3H6xX(CmWxp3w&-8AWjB zYgtT+<0zoW{KYF7Lr8y8<<`lVLby%z@#HzLTon1h(SsnY8*yI0LFcSq2*n1`=12cc z|zhNP*|v0Dsb$On0gza_VAtHABmgE!1*3WPX*s5MyT!19jhdNBUH+&pQ2oXoZdKK7ku zru&eMd134Gt(vXqLSyz`O@9-FxkSIVyO9ZX#?q&axmMwQ*vsL;olcGGgQxdvgB8*-r=ESxwPg`R zli0H?QWhb>ByRGPP&#}oum7lu_vyzU#@b1DmLTf*hs1vdQbCtYO*<0Ls}~%H))TAe zP}Znz|KA$yBRy^Zv@~b~*c+-iHm6!q*26qi8iQ1jIqXgwk%)8k%0D49=^=Dzn7sbz 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 z⊁Q4p;2zPbPW6r46-b7f_U1M?3@#Laklf`TH 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

7tYJf#6Jp# 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�y;i1yBa2sERnXo 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

;Mcchjfy#g3EvZ!aej&MR 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%0DUvn#eA(2}b#n#w=0_;RsZ|ZZ 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Μ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°>30-&u-o=0rfjwo^Ao%;H42#DEey= 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

|4~$kLUh%{{*$JN%X}#iz|X2=apvP_u9Q*L{!CD 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

{_a>~f(0P5HGDAEFgn#IsZqOe^Zi_66%f72f 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 z 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%0AI}Wu1KBnc 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 >c=BR49E$t)=%HE`aQwVvYNg%{ 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

`bfZfdREhN`y3qf-Lb(dUJ&(h-$V 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

    p!Cl3$&H(fGDe# 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%0DBMk?=^R=VA`0vk5 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 kvItug_rYP{rvH57XWk63!lQ%I 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≠bgTPOVThAahi7+ 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ΩQsO$2+PdthtdkSH{ne5IH{iEVf-TI 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
      >-=8_47mx;|7o`@=9}Mi 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 From 0d5e323d97abc2cb0a167daef2772e7f22da14d4 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 20 Jun 2023 16:18:21 -0400 Subject: [PATCH 052/362] removes ipywidgets dependency --- py4DSTEM/utils/configuration_checker.py | 2 -- setup.py | 1 - 2 files changed, 3 deletions(-) diff --git a/py4DSTEM/utils/configuration_checker.py b/py4DSTEM/utils/configuration_checker.py index 859443723..0ccf633fc 100644 --- a/py4DSTEM/utils/configuration_checker.py +++ b/py4DSTEM/utils/configuration_checker.py @@ -15,7 +15,6 @@ 'gdown', 'h5py', 'ipyparallel', - 'ipywidgets', 'jax', 'matplotlib', 'mp_api', @@ -42,7 +41,6 @@ 'matplotlib', 'skimage', 'sklearn', - 'ipywidgets', 'tqdm', 'dill', 'gdown', diff --git a/setup.py b/setup.py index 06c85ea70..e3bc5b568 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,6 @@ 'matplotlib >= 3.2.2', 'scikit-image >= 0.17.2', 'scikit-learn >= 0.23.2', - 'ipywidgets >= 7.6.3', 'tqdm >= 4.46.1', 'dill >= 0.3.3', 'gdown >= 4.4.0', From 4f8f781e267ecb260c1982820ae64ae53e0b94cb Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 20 Jun 2023 16:08:48 -0700 Subject: [PATCH 053/362] re-introducing Fourier probe amplitude fixing --- .../iterative_ptychographic_constraints.py | 31 +++++++ .../iterative_singleslice_ptychography.py | 80 ++++++++++++------- 2 files changed, 80 insertions(+), 31 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 10b24eb78..274e86f39 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -486,6 +486,37 @@ def _probe_fourier_amplitude_constraint( return updated_probe * normalization + def _probe_aperture_constraint( + self, + current_probe, + initial_probe_aperture, + ): + """ + Ptychographic constraint to fix Fourier amplitude to initial aperture. + + Parameters + ---------- + current_probe: np.ndarray + Current positions estimate + + Returns + -------- + constrained_probe: np.ndarray + Constrained probe estimate + """ + xp = self._xp + + current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + current_probe_fft_phase = xp.angle(xp.fft.fft2(current_probe)) + + updated_probe = xp.fft.ifft2( + xp.exp(1j * current_probe_fft_phase) * initial_probe_aperture + ) + updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + + return updated_probe * normalization + def _probe_residual_aberration_filtering_constraint( self, current_probe, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 1cf9e4e44..7f40995d9 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -427,6 +427,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -980,11 +981,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1020,17 +1023,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1102,17 +1109,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1140,12 +1152,13 @@ def reconstruct( pure_phase_object_iter: int = 0, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1199,17 +1212,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -1545,13 +1560,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter From 72171c40246a68ff39d1acd36e91ae26c576b9e6 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 20 Jun 2023 19:18:11 -0400 Subject: [PATCH 054/362] renames io test dir --- .../test_realslice_read.py | 0 .../test_single_object_io.py | 0 test/{test_native_readwrite => test_native_io}/test_v0_13.py | 0 test/{test_native_readwrite => test_native_io}/test_v0_14.py | 0 test/{test_native_readwrite => test_native_io}/test_v0_9.py | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename test/{test_native_readwrite => test_native_io}/test_realslice_read.py (100%) rename test/{test_native_readwrite => test_native_io}/test_single_object_io.py (100%) rename test/{test_native_readwrite => test_native_io}/test_v0_13.py (100%) rename test/{test_native_readwrite => test_native_io}/test_v0_14.py (100%) rename test/{test_native_readwrite => test_native_io}/test_v0_9.py (100%) diff --git a/test/test_native_readwrite/test_realslice_read.py b/test/test_native_io/test_realslice_read.py similarity index 100% rename from test/test_native_readwrite/test_realslice_read.py rename to test/test_native_io/test_realslice_read.py diff --git a/test/test_native_readwrite/test_single_object_io.py b/test/test_native_io/test_single_object_io.py similarity index 100% rename from test/test_native_readwrite/test_single_object_io.py rename to test/test_native_io/test_single_object_io.py diff --git a/test/test_native_readwrite/test_v0_13.py b/test/test_native_io/test_v0_13.py similarity index 100% rename from test/test_native_readwrite/test_v0_13.py rename to test/test_native_io/test_v0_13.py diff --git a/test/test_native_readwrite/test_v0_14.py b/test/test_native_io/test_v0_14.py similarity index 100% rename from test/test_native_readwrite/test_v0_14.py rename to test/test_native_io/test_v0_14.py diff --git a/test/test_native_readwrite/test_v0_9.py b/test/test_native_io/test_v0_9.py similarity index 100% rename from test/test_native_readwrite/test_v0_9.py rename to test/test_native_io/test_v0_9.py From 0770cd5e95e47ec501f368a8459f97e3bb33c74a Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 21 Jun 2023 01:54:45 -0400 Subject: [PATCH 055/362] rms RootedNode --- docs/source/api/emd.rst | 3 +-- py4DSTEM/classes/datacube.py | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/api/emd.rst b/docs/source/api/emd.rst index 660f9777f..8e4223496 100644 --- a/docs/source/api/emd.rst +++ b/docs/source/api/emd.rst @@ -12,7 +12,6 @@ Classes .. autoclass:: emdfile.PointList .. autoclass:: emdfile.PointListArray .. autoclass:: emdfile.Root -.. autoclass:: emdfile.RootedNode Functions @@ -26,4 +25,4 @@ Functions .. autofunction:: emdfile.read .. autofunction:: emdfile.save .. autofunction:: emdfile.set_author -.. autofunction:: emdfile.tqdmnd \ No newline at end of file +.. autofunction:: emdfile.tqdmnd diff --git a/py4DSTEM/classes/datacube.py b/py4DSTEM/classes/datacube.py index 3f2edcf62..169b5fa07 100644 --- a/py4DSTEM/classes/datacube.py +++ b/py4DSTEM/classes/datacube.py @@ -3,11 +3,11 @@ from typing import Optional,Union import numpy as np -from emdfile import Array,RootedNode +from emdfile import Array from py4DSTEM.classes import Data, Calibration from py4DSTEM.classes.methods import DataCubeMethods -class DataCube(Array,RootedNode,Data,DataCubeMethods): +class DataCube(Array,Data,DataCubeMethods): """ Storage and processing methods for 4D-STEM datasets. """ @@ -53,7 +53,8 @@ def __init__( ) # set up EMD tree - RootedNode.__init__(self) + root = Root( name = name+"_root" ) + root.add( self ) # set up calibration self._setup_calibration( calibration ) From 447822f3603ec227ee031d29d05af64a32a7f3f4 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Wed, 21 Jun 2023 09:40:28 -0700 Subject: [PATCH 056/362] Fourier probe amplitude fixing in rest of classes --- .../iterative_mixedstate_ptychography.py | 69 +++++++------ .../iterative_multislice_ptychography.py | 80 ++++++++++------ .../iterative_overlap_magnetic_tomography.py | 94 +++++++++++------- .../phase/iterative_overlap_tomography.py | 96 +++++++++++-------- .../iterative_simultaneous_ptychography.py | 80 ++++++++++------ 5 files changed, 255 insertions(+), 164 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 4b2187a15..afa565871 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -459,6 +459,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = None # Doesn't really make sense for mixed-state self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1083,11 +1084,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1124,17 +1127,21 @@ def _constraints( If True, only the probe phase is smoothed symmetrize_probe: bool If True, the probe is radially-averaged - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray + initial probe aperture to use in replacing probe fourier amplitude fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1203,9 +1210,11 @@ def _constraints( raise NotImplementedError() if symmetrize_probe: raise NotImplementedError() - if fix_probe_amplitude: + if fix_probe_aperture: raise NotImplementedError() - elif fix_probe_fourier_amplitude: + elif constrain_probe_amplitude: + raise NotImplementedError() + elif constrain_probe_fourier_amplitude: raise NotImplementedError() if orthogonalize_probe: @@ -1237,12 +1246,13 @@ def reconstruct( fix_com: bool = True, orthogonalize_probe: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, @@ -1295,17 +1305,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -1637,13 +1649,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index ce8d13325..a67bd93e9 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -521,6 +521,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1432,11 +1433,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1477,17 +1480,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool + If True, probe Fourier amplitude is replaced by initial_probe_aperture + initial_probe_aperture: np.ndarray + Initial probe aperture to use in replacing probe Fourier amplitude fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1589,17 +1596,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1626,12 +1638,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1692,17 +1705,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2049,13 +2064,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 3c33d46f5..92905cac2 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -707,6 +707,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1662,11 +1663,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1704,17 +1707,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1813,17 +1820,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1850,12 +1862,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1912,17 +1925,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2398,14 +2413,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 - < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter @@ -2450,13 +2467,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 4a64f17af..6166640f4 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -616,6 +616,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1510,11 +1511,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1548,17 +1551,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1626,17 +1633,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1663,12 +1675,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1722,17 +1735,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional - Number of iterations to run with a fixed probe before updating probe estimate - fix_probe_amplitude: bool + Number of iterations to run before radially-averaging the probe + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2127,14 +2142,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 - < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter @@ -2174,13 +2191,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index e872bc42e..da358e089 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -694,6 +694,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -2181,11 +2182,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -2219,17 +2222,21 @@ def _constraints( If True, probe CoM is fixed to the center symmetrize_probe: bool If True, the probe is radially-averaged - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -2335,17 +2342,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -2374,12 +2386,13 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, warmup_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -2436,17 +2449,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2811,13 +2826,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, warmup_iteration=a0 < warmup_iter, From a4f1b33478669a932cf72f37ab9e741f39b4ee5a Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 22 Jun 2023 08:04:38 -0400 Subject: [PATCH 057/362] abTEM 2D, text reformat, array docs --- py4DSTEM/io/filereaders/read_abTEM.py | 60 ++-- py4DSTEM/io/importfile.py | 24 +- .../legacy/legacy13/v13_emd_classes/array.py | 6 +- py4DSTEM/io/parsefiletype.py | 32 +- py4DSTEM/io/read.py | 92 ++--- py4DSTEM/process/virtualdiffraction.py | 198 ++++++----- py4DSTEM/process/virtualimage.py | 323 +++++++++--------- 7 files changed, 396 insertions(+), 339 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index 1008bcc0e..af0c71c63 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -1,5 +1,5 @@ import h5py -from py4DSTEM.classes import DataCube +from py4DSTEM.classes import DataCube, VirtualDiffraction, VirtualImage def read_abTEM( @@ -8,7 +8,7 @@ def read_abTEM( binfactor: int = 1, ): """ - File reader for abTEM 4D-STEM datasets + File reader for abTEM datasets Args: filename: str with path to file mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is @@ -30,29 +30,39 @@ def read_abTEM( datasets[key] = f.get(key)[()] data = datasets["array"] - assert len(data.shape) == 4, "reader is for 4D-STEM datasets only" - - datacube = DataCube(data=data) - sampling = datasets["sampling"] units = datasets["units"] - datacube.calibration.set_R_pixel_size(sampling[0]) - if sampling[0] != sampling[1]: - print( - "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" - ) - datacube.calibration.set_Q_pixel_size(sampling[2]) - if sampling[2] != sampling[3]: - print( - "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with qx calibration" - ) - - if units[0] == b"\xc3\x85": - datacube.calibration.set_R_pixel_units("A") - else: - datacube.calibration.set_R_pixel_units(units[0].decode("utf-8")) - - datacube.calibration.set_Q_pixel_units(units[2].decode("utf-8")) - - return datacube + if len(data.shape) == 4: + + datacube = DataCube(data=data) + + datacube.calibration.set_R_pixel_size(sampling[0]) + if sampling[0] != sampling[1]: + print( + "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" + ) + datacube.calibration.set_Q_pixel_size(sampling[2]) + if sampling[2] != sampling[3]: + print( + "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with qx calibration" + ) + + if units[0] == b"\xc3\x85": + datacube.calibration.set_R_pixel_units("A") + else: + datacube.calibration.set_R_pixel_units(units[0].decode("utf-8")) + + datacube.calibration.set_Q_pixel_units(units[2].decode("utf-8")) + + return datacube + + elif len(data.shape) == 2: + if units[0] == b"mrad": + diffraction = VirtualDiffraction(data=data) + # TODO, calibrations for 2D + return diffraction + elif units[0] == b"\xc3\x85": + image = VirtualImage(data=data) + # TODO calibrations for 2D + return image diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 98ef05238..20a3759a2 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -1,18 +1,18 @@ # Reader functions for non-native file types import pathlib -from os.path import exists, splitext -from typing import Union, Optional +from os.path import exists +from typing import Optional, Union -from py4DSTEM.io.parsefiletype import _parse_filetype from py4DSTEM.io.filereaders import ( - read_empad, - read_dm, - read_gatan_K2_bin, load_mib, + read_abTEM, read_arina, - read_abTEM + read_dm, + read_empad, + read_gatan_K2_bin, ) +from py4DSTEM.io.parsefiletype import _parse_filetype def import_file( @@ -56,9 +56,7 @@ def import_file( "RAM", "MEMMAP", ], 'Error: argument mem must be either "RAM" or "MEMMAP"' - assert isinstance( - binfactor, int - ), "Error: argument binfactor must be an integer" + assert isinstance(binfactor, int), "Error: argument binfactor must be an integer" assert binfactor >= 1, "Error: binfactor must be >= 1" if binfactor > 1: assert ( @@ -67,8 +65,10 @@ def import_file( filetype = _parse_filetype(filepath) if filetype is None else filetype - if filetype in ('emd', 'legacy'): - raise Exception("EMD file or py4DSTEM detected - use py4DSTEM.read, not py4DSTEM.import_file!") + if filetype in ("emd", "legacy"): + raise Exception( + "EMD file or py4DSTEM detected - use py4DSTEM.read, not py4DSTEM.import_file!" + ) assert filetype in [ "dm", "empad", diff --git a/py4DSTEM/io/legacy/legacy13/v13_emd_classes/array.py b/py4DSTEM/io/legacy/legacy13/v13_emd_classes/array.py index 4b385a694..8b20779f8 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_emd_classes/array.py +++ b/py4DSTEM/io/legacy/legacy13/v13_emd_classes/array.py @@ -322,8 +322,10 @@ def set_dim( values for the n'th dim vector. Accepts: n (int): specifies which dim vector - dim (list or array): length must be either 2, or equal to the - length of the n'th axis of the data array + dim (list or array): length must be either 1 or 2, or equal to the + length of the n'th axis of the data array. If length is 1 specifies step + size of dim vector and starts at 0. If length is 2, specifies start + and step of dim vector. units (Optional, str): name: (Optional, str): """ diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index ab7529ec6..8d5870944 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -1,12 +1,14 @@ # File parser utility from os.path import splitext -import py4DSTEM.io.legacy as legacy + import emdfile as emd import h5py +import py4DSTEM.io.legacy as legacy + def _parse_filetype(fp): - """ + """ Accepts a path to a data file, and returns the file type as a string. """ _, fext = splitext(fp) @@ -28,7 +30,7 @@ def _parse_filetype(fp): elif _is_abTEM(fp): return "abTEM" - + elif fext in [ ".dm", ".dm3", @@ -36,42 +38,42 @@ def _parse_filetype(fp): ]: return "dm" elif fext in [".raw"]: - return "empad" + return "empad" elif fext in [".mrc"]: - return "mrc_relativity" + return "mrc_relativity" elif fext in [".gtg", ".bin"]: - return "gatan_K2_bin" + return "gatan_K2_bin" elif fext in [".kitware_counted"]: - return "kitware_counted" + return "kitware_counted" elif fext in [".mib", ".MIB"]: return "mib" else: raise Exception(f"Unrecognized file extension {fext}.") + def _is_arina(filepath): """ Check if an h5 file is an Arina file. """ - with h5py.File(filepath,'r') as f: + with h5py.File(filepath, "r") as f: try: - assert("entry" in f.keys()) + assert "entry" in f.keys() except AssertionError: return False try: - assert("NX_class" in f["entry"].attrs.keys()) + assert "NX_class" in f["entry"].attrs.keys() except AssertionError: return False return True + def _is_abTEM(filepath): """ - Check if an h5 file is an abTEM file. + Check if an h5 file is an abTEM file. """ - with h5py.File(filepath,'r') as f: + with h5py.File(filepath, "r") as f: try: - assert("array" in f.keys()) + assert "array" in f.keys() except AssertionError: return False return True - - diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 82815779f..de7359ce8 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -1,24 +1,21 @@ # Reader for native files -from pathlib import Path from os.path import exists -from typing import Optional,Union +from pathlib import Path +from typing import Optional, Union -import py4DSTEM import emdfile as emd -from py4DSTEM.io.parsefiletype import _parse_filetype import py4DSTEM.io.legacy as legacy - - +from py4DSTEM.io.parsefiletype import _parse_filetype def read( - filepath: Union[str,Path], + filepath: Union[str, Path], datapath: Optional[str] = None, - tree: Optional[Union[bool,str]] = True, + tree: Optional[Union[bool, str]] = True, verbose: Optional[bool] = False, **kwargs, - ): +): """ A file reader for native py4DSTEM / EMD files. To read non-native formats, use `py4DSTEM.import_file`. @@ -65,85 +62,90 @@ def read( # parse filetype er1 = f"filepath must be a string or Path, not {type(filepath)}" er2 = f"specified filepath '{filepath}' does not exist" - assert(isinstance(filepath, (str,Path) )), er1 - assert(exists(filepath)), er2 + assert isinstance(filepath, (str, Path)), er1 + assert exists(filepath), er2 filetype = _parse_filetype(filepath) - assert filetype in ('emd', 'legacy'), f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" - + assert filetype in ( + "emd", + "legacy", + ), f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" # EMD 1.0 formatted files (py4DSTEM v0.14+) if filetype == "emd": version = emd._get_EMD_version(filepath) - if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") - assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" - data = emd.read( - filepath, - emdpath = datapath, - tree = tree - ) - if verbose: print("Done.") + if verbose: + print( + f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading..." + ) + assert emd._version_is_geq( + version, (1, 0, 0) + ), f"EMD version {version} detected. Expected version >= 1.0.0" + data = emd.read(filepath, emdpath=datapath, tree=tree) + if verbose: + print("Done.") return data - # legacy py4DSTEM files (v <= 0.13) else: - assert filetype == "legacy", "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." - + assert ( + filetype == "legacy" + ), "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." # read v13 if legacy.is_py4DSTEM_version13(filepath): # load the data - if verbose: print(f"Legacy py4DSTEM version 13 file detected. Reading...") - kwargs['root'] = datapath - kwargs['tree'] = tree + if verbose: + print("Legacy py4DSTEM version 13 file detected. Reading...") + kwargs["root"] = datapath + kwargs["tree"] = tree data = legacy.read_legacy13( filepath=filepath, **kwargs, ) - if verbose: print("Done.") + if verbose: + print("Done.") return data - # read <= v12 else: # parse the root/data_id from the datapath arg if datapath is not None: - datapath = datapath.split('/') + datapath = datapath.split("/") try: - datapath.remove('') + datapath.remove("") except ValueError: pass rootgroup = datapath[0] - if len(datapath)>1: - datapath = '/'.join(rootgroup[1:]) + if len(datapath) > 1: + datapath = "/".join(rootgroup[1:]) else: datapath = None else: rootgroups = legacy.get_py4DSTEM_topgroups(filepath) - if len(rootgroups)>1: - print('multiple root groups in a legacy file found - returning list of root names; please pass one as `datapath`') + if len(rootgroups) > 1: + print( + "multiple root groups in a legacy file found - returning list of root names; please pass one as `datapath`" + ) return rootgroups - elif len(rootgroups)==0: - raise Exception('No rootgroups found') + elif len(rootgroups) == 0: + raise Exception("No rootgroups found") else: rootgroup = rootgroups[0] datapath = None - # load the data - if verbose: print(f"Legacy py4DSTEM version <= 12 file detected. Reading...") - kwargs['topgroup'] = rootgroup + if verbose: + print("Legacy py4DSTEM version <= 12 file detected. Reading...") + kwargs["topgroup"] = rootgroup if datapath is not None: - kwargs['data_id'] = datapath + kwargs["data_id"] = datapath data = legacy.read_legacy12( filepath=filepath, **kwargs, ) - if verbose: print("Done.") + if verbose: + print("Done.") return data - - - diff --git a/py4DSTEM/process/virtualdiffraction.py b/py4DSTEM/process/virtualdiffraction.py index ba31b778a..b54aed65d 100644 --- a/py4DSTEM/process/virtualdiffraction.py +++ b/py4DSTEM/process/virtualdiffraction.py @@ -3,17 +3,18 @@ import numpy as np from emdfile import tqdmnd + def get_virtual_diffraction( datacube, method, - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - return_mask = False, + mode=None, + geometry=None, + calibrated=False, + shift_center=False, + verbose=True, + return_mask=False, ): - ''' + """ Function to calculate virtual diffraction Args: @@ -58,36 +59,54 @@ def get_virtual_diffraction( Returns: (2D array): the diffraction image - ''' + """ - assert method in ('max', 'median', 'mean'),\ - 'check doc strings for supported types' + assert method in ("max", "median", "mean"), "check doc strings for supported types" - #create mask + # create mask if mode is not None: use_all_points = False from py4DSTEM.process.virtualimage import make_detector - assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ - 'check doc strings for supported modes' + + assert mode in ( + "point", + "circle", + "circular", + "annulus", + "annular", + "rectangle", + "square", + "rectangular", + "mask", + ), "check doc strings for supported modes" g = geometry if calibrated == True: - assert datacube.calibration['R_pixel_units'] == 'A', \ - 'check datacube.calibration. datacube must be calibrated in A to use `calibrated=True`' - - unit_conversion = datacube.calibration['R_pixel_size'] - if mode == 'point': - g = (g[0]/unit_conversion, g[1]/unit_conversion) - if mode in('circle', 'circular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1]/unit_conversion)) - if mode in('annulus', 'annular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1][0]/unit_conversion, g[1][1]/unit_conversion)) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0]/unit_conversion, g[1]/unit_conversion, - g[2]/unit_conversion, g[3]/unit_conversion) + assert ( + datacube.calibration["R_pixel_units"] == "A" + ), "check datacube.calibration. datacube must be calibrated in A to use `calibrated=True`" + + unit_conversion = datacube.calibration["R_pixel_size"] + if mode == "point": + g = (g[0] / unit_conversion, g[1] / unit_conversion) + if mode in ("circle", "circular"): + g = ( + (g[0][0] / unit_conversion, g[0][1] / unit_conversion), + (g[1] / unit_conversion), + ) + if mode in ("annulus", "annular"): + g = ( + (g[0][0] / unit_conversion, g[0][1] / unit_conversion), + (g[1][0] / unit_conversion, g[1][1] / unit_conversion), + ) + if mode in ("rectangle", "square", "rectangular"): + g = ( + g[0] / unit_conversion, + g[1] / unit_conversion, + g[2] / unit_conversion, + g[3] / unit_conversion, + ) # Get mask mask = make_detector(datacube.Rshape, mode, g) @@ -99,7 +118,7 @@ def get_virtual_diffraction( else: mask_is_boolean = False - #if no mask + # if no mask else: mask = np.ones(datacube.Rshape, dtype=bool) mask_indices = np.nonzero(mask) @@ -117,48 +136,62 @@ def get_virtual_diffraction( # ...for the whole pattern if use_all_points: - if method == 'mean': - virtual_diffraction = np.mean(datacube.data, axis=(0,1)) - elif method == 'max': - virtual_diffraction = np.max(datacube.data, axis=(0,1)) + if method == "mean": + virtual_diffraction = np.mean(datacube.data, axis=(0, 1)) + elif method == "max": + virtual_diffraction = np.max(datacube.data, axis=(0, 1)) else: - virtual_diffraction = np.median(datacube.data, axis=(0,1)) + virtual_diffraction = np.median(datacube.data, axis=(0, 1)) # ...for boolean masks elif mask_is_boolean: - if method == 'mean': - virtual_diffraction = np.mean(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) - elif method == 'max': - virtual_diffraction = np.max(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) + if method == "mean": + virtual_diffraction = np.mean( + datacube.data[mask_indices[0], mask_indices[1], :, :], axis=0 + ) + elif method == "max": + virtual_diffraction = np.max( + datacube.data[mask_indices[0], mask_indices[1], :, :], axis=0 + ) else: - virtual_diffraction = np.median(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) + virtual_diffraction = np.median( + datacube.data[mask_indices[0], mask_indices[1], :, :], axis=0 + ) # ...for floating point masks else: - if mask.dtype == 'complex': - virtual_diffraction = np.zeros(datacube.Qshape, dtype = 'complex') + if mask.dtype == "complex": + virtual_diffraction = np.zeros(datacube.Qshape, dtype="complex") else: virtual_diffraction = np.zeros(datacube.Qshape) - for qx,qy in tqdmnd( + for qx, qy in tqdmnd( datacube.Q_Nx, datacube.Q_Ny, - disable = not verbose, + disable=not verbose, ): - if method == 'mean': - virtual_diffraction[qx,qy] = np.sum( np.squeeze(datacube.data[:,:,qx,qy])*mask ) - elif method == 'max': - virtual_diffraction[qx,qy] = np.max( np.squeeze(datacube.data[:,:,qx,qy])*mask ) - elif method == 'median': - virtual_diffraction[qx,qy] = np.median( np.squeeze(datacube.data[:,:,qx,qy])*mask ) + if method == "mean": + virtual_diffraction[qx, qy] = np.sum( + np.squeeze(datacube.data[:, :, qx, qy]) * mask + ) + elif method == "max": + virtual_diffraction[qx, qy] = np.max( + np.squeeze(datacube.data[:, :, qx, qy]) * mask + ) + elif method == "median": + virtual_diffraction[qx, qy] = np.median( + np.squeeze(datacube.data[:, :, qx, qy]) * mask + ) # norm by weighting term for means - if method == 'mean' and not use_all_points: + if method == "mean" and not use_all_points: virtual_diffraction /= np.sum(mask) # ...with center shifting else: - assert method in ('max', 'mean'),\ - "only 'mean' and 'max' are supported for center-shifted virtual diffraction" + assert method in ( + "max", + "mean", + ), "only 'mean' and 'max' are supported for center-shifted virtual diffraction" # Get calibration metadata assert datacube.calibration.get_origin(), "origin needs to be calibrated" @@ -166,58 +199,65 @@ def get_virtual_diffraction( x0_mean, y0_mean = datacube.calibration.get_origin_mean() # get shifts - qx_shift = (x0_mean-x0).round().astype(int) - qy_shift = (y0_mean-y0).round().astype(int) - + qx_shift = (x0_mean - x0).round().astype(int) + qy_shift = (y0_mean - y0).round().astype(int) # compute... # ...for boolean masks / whole datacubes if mask_is_boolean or use_all_points: virtual_diffraction = np.zeros(datacube.Qshape) - for rx,ry in zip(mask_indices[0],mask_indices[1]): + for rx, ry in zip(mask_indices[0], mask_indices[1]): # get shifted DP DP = np.roll( - datacube.data[rx,ry, :,:,], - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1), - ) + datacube.data[ + rx, + ry, + :, + :, + ], + (qx_shift[rx, ry], qy_shift[rx, ry]), + axis=(0, 1), + ) # compute - if method == 'mean': + if method == "mean": virtual_diffraction += DP - elif method == 'max': + elif method == "max": virtual_diffraction = np.maximum(virtual_diffraction, DP) - if method == 'mean': + if method == "mean": virtual_diffraction /= len(mask_indices[0]) # ...for floating point masks else: - if mask.dtype == 'complex': - virtual_diffraction = np.zeros(datacube.Qshape, dtype = 'complex') + if mask.dtype == "complex": + virtual_diffraction = np.zeros(datacube.Qshape, dtype="complex") else: virtual_diffraction = np.zeros(datacube.Qshape) - for rx,ry in tqdmnd( + for rx, ry in tqdmnd( datacube.R_Nx, datacube.R_Ny, - disable = not verbose, + disable=not verbose, ): # get shifted DP DP = np.roll( - datacube.data[rx,ry, :,:,], - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1), - ) + datacube.data[ + rx, + ry, + :, + :, + ], + (qx_shift[rx, ry], qy_shift[rx, ry]), + axis=(0, 1), + ) # compute - w = mask[rx,ry] + w = mask[rx, ry] if w > 0: - if method == 'mean': - virtual_diffraction += DP*w - elif method == 'max': - virtual_diffraction = np.maximum(virtual_diffraction, DP*w) - if method == 'mean': + if method == "mean": + virtual_diffraction += DP * w + elif method == "max": + virtual_diffraction = np.maximum(virtual_diffraction, DP * w) + if method == "mean": virtual_diffraction /= np.sum(mask) # return return virtual_diffraction - - diff --git a/py4DSTEM/process/virtualimage.py b/py4DSTEM/process/virtualimage.py index 1c5e5e1da..cb50da774 100644 --- a/py4DSTEM/process/virtualimage.py +++ b/py4DSTEM/process/virtualimage.py @@ -1,22 +1,23 @@ # Functions for generating virtual images -import numpy as np import dask.array as da +import numpy as np from emdfile import tqdmnd from py4DSTEM.classes import Calibration + def get_virtual_image( datacube, mode, geometry, - centered = False, - calibrated = False, - shift_center = False, - verbose = True, - dask = False, - return_mask = False, - test_config = False + centered=False, + calibrated=False, + shift_center=False, + verbose=True, + dask=False, + return_mask=False, + test_config=False, ): - ''' + """ Function to calculate virtual image Args: @@ -72,25 +73,30 @@ def get_virtual_image( Returns: (2D array) virtual image - ''' + """ - assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ - 'check doc strings for supported modes' + assert mode in ( + "point", + "circle", + "circular", + "annulus", + "annular", + "rectangle", + "square", + "rectangular", + "mask", + ), "check doc strings for supported modes" if shift_center == True: assert centered, "centered must be True if shift_center is True" if test_config: - for x,y in zip(['centered','calibrated','shift_center'], - [centered,calibrated,shift_center]): + for x, y in zip( + ["centered", "calibrated", "shift_center"], + [centered, calibrated, shift_center], + ): print(f"{x} = {y}") # Get geometry - g = get_calibrated_geometry( - datacube, - mode, - geometry, - centered, - calibrated - ) + g = get_calibrated_geometry(datacube, mode, geometry, centered, calibrated) # Get mask mask = make_detector(datacube.Qshape, mode, g) @@ -98,22 +104,25 @@ def get_virtual_image( if return_mask == True and shift_center == False: return mask - # Calculate images # no center shifting if shift_center == False: - # dask + # dask if dask == True: # set up a generalized universal function for dask distribution - def _apply_mask_dask(datacube,mask): - virtual_image = np.sum(np.multiply(datacube.data,mask), dtype=np.float64) + def _apply_mask_dask(datacube, mask): + virtual_image = np.sum( + np.multiply(datacube.data, mask), dtype=np.float64 + ) + apply_mask_dask = da.as_gufunc( - _apply_mask_dask,signature='(i,j),(i,j)->()', + _apply_mask_dask, + signature="(i,j),(i,j)->()", output_dtypes=np.float64, - axes=[(2,3),(0,1),()], - vectorize=True + axes=[(2, 3), (0, 1), ()], + vectorize=True, ) # compute @@ -123,69 +132,57 @@ def _apply_mask_dask(datacube,mask): else: # compute - if mask.dtype == 'complex': - virtual_image = np.zeros(datacube.Rshape, dtype = 'complex') + if mask.dtype == "complex": + virtual_image = np.zeros(datacube.Rshape, dtype="complex") else: virtual_image = np.zeros(datacube.Rshape) - for rx,ry in tqdmnd( + for rx, ry in tqdmnd( datacube.R_Nx, datacube.R_Ny, - disable = not verbose, + disable=not verbose, ): - virtual_image[rx,ry] = np.sum(datacube.data[rx,ry]*mask) + virtual_image[rx, ry] = np.sum(datacube.data[rx, ry] * mask) # with center shifting else: # get shifts assert datacube.calibration.get_origin_shift(), "origin need to be calibrated" - qx_shift,qy_shift = datacube.calibration.get_origin_shift() + qx_shift, qy_shift = datacube.calibration.get_origin_shift() qx_shift = qx_shift.round().astype(int) qy_shift = qy_shift.round().astype(int) # if return_mask is True, skip computation if return_mask is not False: try: - rx,ry = return_mask + rx, ry = return_mask except TypeError: - raise Exception("when `shift_center` is True, return_mask must be a 2-tuple of ints or False") + raise Exception( + "when `shift_center` is True, return_mask must be a 2-tuple of ints or False" + ) # get shifted mask - _mask = np.roll( - mask, - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1) - ) + _mask = np.roll(mask, (qx_shift[rx, ry], qy_shift[rx, ry]), axis=(0, 1)) return _mask # compute - if mask.dtype == 'complex': - virtual_image = np.zeros(datacube.Rshape, dtype = 'complex') + if mask.dtype == "complex": + virtual_image = np.zeros(datacube.Rshape, dtype="complex") else: virtual_image = np.zeros(datacube.Rshape) - for rx,ry in tqdmnd( + for rx, ry in tqdmnd( datacube.R_Nx, datacube.R_Ny, - disable = not verbose, + disable=not verbose, ): # get shifted mask - _mask = np.roll( - mask, - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1) - ) - virtual_image[rx,ry] = np.sum(datacube.data[rx,ry]*_mask) + _mask = np.roll(mask, (qx_shift[rx, ry], qy_shift[rx, ry]), axis=(0, 1)) + virtual_image[rx, ry] = np.sum(datacube.data[rx, ry] * _mask) return virtual_image -def get_calibrated_geometry( - calibration, - mode, - geometry, - centered, - calibrated - ): +def get_calibrated_geometry(calibration, mode, geometry, centered, calibrated): """ Determine the detector geometry in pixels, given some mode and geometry in calibrated units, where the calibration state is specified by { @@ -213,9 +210,13 @@ def get_calibrated_geometry( else: try: cal = calibration.calibration - assert isinstance(cal, Calibration), "`calibration.calibration` must be a Calibration instance" + assert isinstance( + cal, Calibration + ), "`calibration.calibration` must be a Calibration instance" except AttributeError: - raise Exception("`calibration` must either be a Calibration instance or have a .calibration attribute") + raise Exception( + "`calibration` must either be a Calibration instance or have a .calibration attribute" + ) # Get calibration metadata if centered: @@ -223,46 +224,53 @@ def get_calibrated_geometry( x0_mean, y0_mean = cal.get_origin_mean() if calibrated: - assert cal['Q_pixel_units'] == 'A^-1', \ - 'check calibration - must be calibrated in A^-1 to use `calibrated=True`' + assert ( + cal["Q_pixel_units"] == "A^-1" + ), "check calibration - must be calibrated in A^-1 to use `calibrated=True`" unit_conversion = cal.get_Q_pixel_size() - # Convert units into detector pixels # Shift center if centered == True: - if mode == 'point': + if mode == "point": g = (g[0] + x0_mean, g[1] + y0_mean) - if mode in('circle', 'circular', 'annulus', 'annular'): + if mode in ("circle", "circular", "annulus", "annular"): g = ((g[0][0] + x0_mean, g[0][1] + y0_mean), g[1]) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0] + x0_mean, g[1] + x0_mean, g[2] + y0_mean, g[3] + y0_mean) + if mode in ("rectangle", "square", "rectangular"): + g = (g[0] + x0_mean, g[1] + x0_mean, g[2] + y0_mean, g[3] + y0_mean) # Scale by the detector pixel size if calibrated == True: - if mode == 'point': - g = (g[0]/unit_conversion, g[1]/unit_conversion) - if mode in('circle', 'circular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1]/unit_conversion)) - if mode in('annulus', 'annular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1][0]/unit_conversion, g[1][1]/unit_conversion)) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0]/unit_conversion, g[1]/unit_conversion, - g[2]/unit_conversion, g[3]/unit_conversion) + if mode == "point": + g = (g[0] / unit_conversion, g[1] / unit_conversion) + if mode in ("circle", "circular"): + g = ( + (g[0][0] / unit_conversion, g[0][1] / unit_conversion), + (g[1] / unit_conversion), + ) + if mode in ("annulus", "annular"): + g = ( + (g[0][0] / unit_conversion, g[0][1] / unit_conversion), + (g[1][0] / unit_conversion, g[1][1] / unit_conversion), + ) + if mode in ("rectangle", "square", "rectangular"): + g = ( + g[0] / unit_conversion, + g[1] / unit_conversion, + g[2] / unit_conversion, + g[3] / unit_conversion, + ) return g - def make_detector( shape, mode, geometry, ): - ''' + """ Function to return 2D mask Args: @@ -291,31 +299,38 @@ def make_detector( Returns: virtual detector in the form of a 2D mask (array) - ''' + """ g = geometry - #point mask - if mode == 'point': - assert(isinstance(g,tuple) and len(g)==2), 'specify qx and qy as tuple (qx, qy)' + # point mask + if mode == "point": + assert ( + isinstance(g, tuple) and len(g) == 2 + ), "specify qx and qy as tuple (qx, qy)" mask = np.zeros(shape, dtype=bool) qx = int(g[0]) qy = int(g[1]) - mask[qx,qy] = 1 + mask[qx, qy] = 1 - #circular mask - if mode in('circle', 'circular'): - assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and isinstance(g[1],(float,int))), \ - 'specify qx, qy, radius_i as ((qx, qy), radius)' + # circular mask + if mode in ("circle", "circular"): + assert ( + isinstance(g, tuple) + and len(g) == 2 + and len(g[0]) == 2 + and isinstance(g[1], (float, int)) + ), "specify qx, qy, radius_i as ((qx, qy), radius)" qxa, qya = np.indices(shape) mask = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1] ** 2 - #annular mask - if mode in('annulus', 'annular'): - assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and len(g[1])==2), \ - 'specify qx, qy, radius_i, radius_0 as ((qx, qy), (radius_i, radius_o))' + # annular mask + if mode in ("annulus", "annular"): + assert ( + isinstance(g, tuple) and len(g) == 2 and len(g[0]) == 2 and len(g[1]) == 2 + ), "specify qx, qy, radius_i, radius_0 as ((qx, qy), (radius_i, radius_o))" assert g[1][1] > g[1][0], "Inner radius must be smaller than outer radius" @@ -324,10 +339,11 @@ def make_detector( mask2 = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1][1] ** 2 mask = np.logical_and(mask1, mask2) - #rectangle mask - if mode in('rectangle', 'square', 'rectangular') : - assert(isinstance(g,tuple) and len(g)==4), \ - 'specify x_min, x_max, y_min, y_max as (x_min, x_max, y_min, y_max)' + # rectangle mask + if mode in ("rectangle", "square", "rectangular"): + assert ( + isinstance(g, tuple) and len(g) == 4 + ), "specify x_min, x_max, y_min, y_max as (x_min, x_max, y_min, y_max)" mask = np.zeros(shape, dtype=bool) xmin = int(np.round(g[0])) @@ -337,13 +353,14 @@ def make_detector( mask[xmin:xmax, ymin:ymax] = 1 - #flexible mask - if mode == 'mask': - assert type(g) == np.ndarray, '`geometry` type should be `np.ndarray`' - assert (g.shape == shape), 'mask and diffraction pattern shapes do not match' + # flexible mask + if mode == "mask": + assert type(g) == np.ndarray, "`geometry` type should be `np.ndarray`" + assert g.shape == shape, "mask and diffraction pattern shapes do not match" mask = g return mask + def make_bragg_mask( Qshape, g1, @@ -351,10 +368,10 @@ def make_bragg_mask( radius, origin, max_q, - return_sum = True, + return_sum=True, **kwargs, - ): - ''' +): + """ Creates and returns a mask consisting of circular disks about the points of a 2D lattice. @@ -370,61 +387,49 @@ def make_bragg_mask( Returns: (2 or 3D array) the mask - ''' + """ nas = np.asarray - g1,g2,origin = nas(g1),nas(g2),nas(origin) + g1, g2, origin = nas(g1), nas(g2), nas(origin) # Get N,M, the maximum indices to tile out to L1 = np.sqrt(np.sum(g1**2)) - H = int(max_q/L1) + 1 - L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) - K = int(max_q/L2) + 1 + H = int(max_q / L1) + 1 + L2 = np.hypot(-g2[0] * g1[1], g2[1] * g1[0]) / np.sqrt(np.sum(g1**2)) + K = int(max_q / L2) + 1 # Compute number of points N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 + for h in range(-H, H + 1): + for k in range(-K, K + 1): + v = h * g1 + k * g2 if np.sqrt(v.dot(v)) < max_q: N += 1 - #create mask + # create mask mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 + for h in range(-H, H + 1): + for k in range(-K, K + 1): + v = h * g1 + k * g2 if np.sqrt(v.dot(v)) < max_q: center = origin + v - mask[:,:,N] = make_detector( + mask[:, :, N] = make_detector( Qshape, - mode = 'circle', - geometry = (center, radius), + mode="circle", + geometry=(center, radius), ) N += 1 - if return_sum: - mask = np.sum(mask, axis = 2) + mask = np.sum(mask, axis=2) return mask - - - - - - - - - - - def get_virtual_image_pointlistarray( peaks, - mode = None, - geometry = None, - ): + mode=None, + geometry=None, +): """ Make a virtual image from a pointlist array. TODO - implement more virtual detectors. @@ -451,62 +456,58 @@ def get_virtual_image_pointlistarray( if mode is None: if geometry is None: center = None - radial_range = np.array((0,np.inf)) + radial_range = np.array((0, np.inf)) else: if len(geometry[0]) == 0: center = None else: center = np.array(geometry[0]) if isinstance(geometry[1], int) or isinstance(geometry[1], float): - radial_range = np.array((0,geometry[1])) + radial_range = np.array((0, geometry[1])) elif len(geometry[1]) == 0: radial_range = None else: radial_range = np.array(geometry[1]) - elif mode == 'circular' or mode == 'circle': - radial_range = np.array((0,geometry[1])) + elif mode == "circular" or mode == "circle": + radial_range = np.array((0, geometry[1])) if len(geometry[0]) == 0: - center = None + center = None else: center = np.array(geometry[0]) - elif mode == 'annular' or mode == 'annulus': + elif mode == "annular" or mode == "annulus": radial_range = np.array(geometry[1]) if len(geometry[0]) == 0: - center = None + center = None else: center = np.array(geometry[0]) - - # init im_virtual = np.zeros(peaks.shape) # Generate image - for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): - p = peaks.get_pointlist(rx,ry) + for rx, ry in tqdmnd(peaks.shape[0], peaks.shape[1]): + p = peaks.get_pointlist(rx, ry) if p.data.shape[0] > 0: if radial_range is None: - im_virtual[rx,ry] = np.sum(p.data['intensity']) + im_virtual[rx, ry] = np.sum(p.data["intensity"]) else: if center is None: - qr = np.hypot(p.data['qx'],p.data['qy']) + qr = np.hypot(p.data["qx"], p.data["qy"]) else: - qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) - sub = np.logical_and( - qr >= radial_range[0], - qr < radial_range[1]) + qr = np.hypot(p.data["qx"] - center[0], p.data["qy"] - center[1]) + sub = np.logical_and(qr >= radial_range[0], qr < radial_range[1]) if np.sum(sub) > 0: - im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) + im_virtual[rx, ry] = np.sum(p.data["intensity"][sub]) return im_virtual def get_virtual_image_braggvectors( bragg_peaks, - mode = None, - geometry = None, - ): - ''' + mode=None, + geometry=None, +): + """ Function to calculate virtual images from braggvectors / pointlist arrays. TODO - implement these detectors for braggvectors @@ -526,12 +527,12 @@ def get_virtual_image_braggvectors( Returns: im_virtual (2D numpy array): the calculated virtual image - ''' + """ virtual_image = get_virtual_image_pointlistarray( bragg_peaks.vectors, - mode = mode, - geometry = geometry, - ) + mode=mode, + geometry=geometry, + ) return virtual_image From fb51d2ed0fe3147942051410082f34ca5712063a Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:59:04 -0400 Subject: [PATCH 058/362] update python version spec --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 710f20a8a..bc206e901 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ author_email='ben.savitzky@gmail.com', license='GNU GPLv3', keywords="STEM 4DSTEM", - python_requires='>=3.9,<=3.11.3', + python_requires='>=3.9,<3.12', install_requires=[ 'numpy >= 1.19', 'scipy >= 1.5.2', From 2a5f5b481dfde642716965cb872f20f9d2aa3b92 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 11:14:03 -0400 Subject: [PATCH 059/362] rms RootedNode --- py4DSTEM/classes/datacube.py | 4 ++-- py4DSTEM/io/sample_file_ids.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/classes/datacube.py b/py4DSTEM/classes/datacube.py index 169b5fa07..d5738e466 100644 --- a/py4DSTEM/classes/datacube.py +++ b/py4DSTEM/classes/datacube.py @@ -3,7 +3,7 @@ from typing import Optional,Union import numpy as np -from emdfile import Array +from emdfile import Array,Root from py4DSTEM.classes import Data, Calibration from py4DSTEM.classes.methods import DataCubeMethods @@ -54,7 +54,7 @@ def __init__( # set up EMD tree root = Root( name = name+"_root" ) - root.add( self ) + root.tree( self ) # set up calibration self._setup_calibration( calibration ) diff --git a/py4DSTEM/io/sample_file_ids.py b/py4DSTEM/io/sample_file_ids.py index b42b7eccc..277f06f47 100644 --- a/py4DSTEM/io/sample_file_ids.py +++ b/py4DSTEM/io/sample_file_ids.py @@ -48,9 +48,9 @@ 'vac_probe.h5', '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', ), - 'small_dm3' : ( - 'small_dm3.dm3', - '1RxI1QY6vYMDqqMVPt5GBN6Q_iCwHFU4B' + 'small_dm3_3Dstack' : ( + 'small_dm3_3Dstack.dm3', + '1B-xX3F65JcWzAg0v7f1aVwnawPIfb5_o' ), 'FCU-Net' : ( 'filename.name', @@ -74,7 +74,7 @@ 'vac_probe', ), 'io_test_data' : ( - 'small_dm3', + 'small_dm3_3Dstack', 'vac_probe', ), } From d3e346c8f764999b616f08f4f9e5724562dffc76 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 11:18:32 -0400 Subject: [PATCH 060/362] bumps emdfile to 0.0.9 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e3bc5b568..2f1e15a63 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ 'gdown >= 4.4.0', 'dask >= 2.3.0', 'distributed >= 2.3.0', - 'emdfile >= 0.0.6', + 'emdfile >= 0.0.9', ], extras_require={ 'ipyparallel': ['ipyparallel >= 6.2.4', 'dill >= 0.3.3'], From 6f9664efa3610f197cc487c83cfa78b56aa3750b Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 11:37:35 -0400 Subject: [PATCH 061/362] renames build-flake.yml --- .github/workflows/{python-app.yml => build-flake.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{python-app.yml => build-flake.yml} (100%) diff --git a/.github/workflows/python-app.yml b/.github/workflows/build-flake.yml similarity index 100% rename from .github/workflows/python-app.yml rename to .github/workflows/build-flake.yml From 547dddef9cf742bd4c2573ab5c74d625965fd6a1 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 11:48:22 -0400 Subject: [PATCH 062/362] restructures test/ --- test/{test_classes => }/test_braggvectors.py | 0 test/test_calibration.py | 40 +++++++++++++++++ test/{test_classes => }/test_crystal.py | 0 test/{test_classes => }/test_datacube.py | 3 +- test/test_native_io/test_calibration_io.py | 44 +++++++++++++++++++ .../test_dm.py | 0 6 files changed, 85 insertions(+), 2 deletions(-) rename test/{test_classes => }/test_braggvectors.py (100%) create mode 100644 test/test_calibration.py rename test/{test_classes => }/test_crystal.py (100%) rename test/{test_classes => }/test_datacube.py (92%) create mode 100644 test/test_native_io/test_calibration_io.py rename test/{test_fileimport => test_nonnative_io}/test_dm.py (100%) diff --git a/test/test_classes/test_braggvectors.py b/test/test_braggvectors.py similarity index 100% rename from test/test_classes/test_braggvectors.py rename to test/test_braggvectors.py diff --git a/test/test_calibration.py b/test/test_calibration.py new file mode 100644 index 000000000..f95ecdbfd --- /dev/null +++ b/test/test_calibration.py @@ -0,0 +1,40 @@ +import py4DSTEM +import numpy as np +from os.path import join + +# set filepath +path = py4DSTEM._TESTPATH + "/io_test_data/small_dm3_3Dstack.dm3" + + + +class TestDataCube: + + # setup/teardown + def setup_class(cls): + + # Read sim Au datacube + datacube = py4DSTEM.import_file(path) + datacube = py4DSTEM.DataCube( + data=datacube.data.reshape((10,10,512,512)) + ) + cls.datacube = datacube + + # tests + + def test_binning_default_dtype(self): + + dtype = self.datacube.data.dtype + assert(dtype == np.uint16) + + self.datacube.bin_Q(2) + + assert(self.datacube.data.dtype == dtype) + + new_dtype = np.uint32 + self.datacube.bin_Q(2, dtype=new_dtype) + + assert(self.datacube.data.dtype == new_dtype) + assert(self.datacube.data.dtype != dtype) + + pass + diff --git a/test/test_classes/test_crystal.py b/test/test_crystal.py similarity index 100% rename from test/test_classes/test_crystal.py rename to test/test_crystal.py diff --git a/test/test_classes/test_datacube.py b/test/test_datacube.py similarity index 92% rename from test/test_classes/test_datacube.py rename to test/test_datacube.py index 57a225abb..f95ecdbfd 100644 --- a/test/test_classes/test_datacube.py +++ b/test/test_datacube.py @@ -3,8 +3,7 @@ from os.path import join # set filepath -path = join(py4DSTEM._TESTPATH, "small_dm3.dm3") - +path = py4DSTEM._TESTPATH + "/io_test_data/small_dm3_3Dstack.dm3" diff --git a/test/test_native_io/test_calibration_io.py b/test/test_native_io/test_calibration_io.py new file mode 100644 index 000000000..7aaa42d30 --- /dev/null +++ b/test/test_native_io/test_calibration_io.py @@ -0,0 +1,44 @@ +import py4DSTEM +import numpy as np +from os.path import join + +# set filepath +path = join(py4DSTEM._TESTPATH, "filename") + + + +class TestCalibrationIO: + + + + def test_datacube_cal_io(self): + # TODO + # make a datacube + # modify its calibration + # save + # load the datacube + # check its calibration + assert 0 + pass + + + def test_datacube_child_node(self): + # TODO + # make a datacube + # make a child node + # confirm calibrations are the same + # modify the calibration + # save + # load the datacube + # check its calibration + # load just the child node + # check its calibration + assert 0 + pass + + + + + + + diff --git a/test/test_fileimport/test_dm.py b/test/test_nonnative_io/test_dm.py similarity index 100% rename from test/test_fileimport/test_dm.py rename to test/test_nonnative_io/test_dm.py From 11dc963c40c399a00e220703d39baadd05ef1224 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 12:13:25 -0400 Subject: [PATCH 063/362] updates to test files --- py4DSTEM/io/sample_file_ids.py | 5 +++++ test/gettestdata.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/py4DSTEM/io/sample_file_ids.py b/py4DSTEM/io/sample_file_ids.py index 277f06f47..b53d63621 100644 --- a/py4DSTEM/io/sample_file_ids.py +++ b/py4DSTEM/io/sample_file_ids.py @@ -56,6 +56,11 @@ 'filename.name', '1-KX0saEYfhZ9IJAOwabH38PCVtfXidJi', ), + 'small_datacube' : ( + 'small_datacube.dm4', + # TODO - change this file to something smaller - ideally e.g. shape (4,8,256,256) ~= 4.2MB' + '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe' + ), } # collections of files diff --git a/test/gettestdata.py b/test/gettestdata.py index eb5e7c5a8..92e3e93e0 100644 --- a/test/gettestdata.py +++ b/test/gettestdata.py @@ -19,6 +19,7 @@ data_options = [ 'tutorials', 'io', + 'basic' ] # Add arguments @@ -54,6 +55,8 @@ data = 'tutorials' elif args.data == 'io': data = 'io_test_data' +elif args.data == 'basic': + data = 'small_datacube' else: raise Exception(f"invalid data choice, {parser.data}") From c1e2cf16c02ef18570cc50e2acd1796f853b6448 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 14:13:54 -0400 Subject: [PATCH 064/362] updates, mv root/cal logic to Data --- py4DSTEM/classes/data.py | 19 +++++++- py4DSTEM/classes/datacube.py | 15 ++++--- test/gettestdata.py | 9 +++- test/test_calibration.py | 74 ++++++++++++++++++++++--------- test/test_datacube.py | 7 +-- test/test_nonnative_io/test_dm.py | 12 +++-- 6 files changed, 98 insertions(+), 38 deletions(-) diff --git a/py4DSTEM/classes/data.py b/py4DSTEM/classes/data.py index 194d5af35..5794b9963 100644 --- a/py4DSTEM/classes/data.py +++ b/py4DSTEM/classes/data.py @@ -3,16 +3,29 @@ import warnings -from emdfile import Node +from emdfile import Node, Root from py4DSTEM.classes import Calibration class Data: - def __init__(self): + def __init__( + self, + setup_tree = True, + calibration = None + ): assert(isinstance(self,Node)), "Data instances must alse inherit from Node" pass + if setup_tree: + # set up EMD tree + root = Root( name = self.name+"_root" ) + root.tree( self ) + + # set up calibration + calibration = Calibration() if calibration is None else calibration + self._setup_calibration( calibration ) + # calibration @@ -21,8 +34,10 @@ def calibration(self): try: return self.root.metadata['calibration'] except KeyError: + warnings.warn("No calibration metadata found in root, returning None") return None except AttributeError: + warnings.warn("No root or root metadata found, returning None") return None @calibration.setter diff --git a/py4DSTEM/classes/datacube.py b/py4DSTEM/classes/datacube.py index d5738e466..964a89ff0 100644 --- a/py4DSTEM/classes/datacube.py +++ b/py4DSTEM/classes/datacube.py @@ -16,8 +16,9 @@ def __init__( self, data: np.ndarray, name: Optional[str] = 'datacube', - calibration: Optional[Union[Calibration,None]] = None, slicelabels: Optional[Union[bool,list]] = None, + setup_tree: Optional[bool] = True, + calibration: Optional[Union[Calibration,None]] = None, ): """ Accepts: @@ -52,12 +53,12 @@ def __init__( slicelabels = slicelabels ) - # set up EMD tree - root = Root( name = name+"_root" ) - root.tree( self ) - - # set up calibration - self._setup_calibration( calibration ) + # initialize as Data + Data.__init__( + self, + setup_tree, + calibration + ) # cartesian coords # TODO - tmp hack, needs to be refactored - diff --git a/test/gettestdata.py b/test/gettestdata.py index 92e3e93e0..a370cdcc1 100644 --- a/test/gettestdata.py +++ b/test/gettestdata.py @@ -68,7 +68,14 @@ verbose = args.verbose ) - +# Always download the basic datacube +if args.data is not 'basic': + download( + 'small_datacube', + destination = testpath, + overwrite = args.overwrite, + verbose = args.verbose + ) diff --git a/test/test_calibration.py b/test/test_calibration.py index f95ecdbfd..eb600fa3a 100644 --- a/test/test_calibration.py +++ b/test/test_calibration.py @@ -1,40 +1,74 @@ import py4DSTEM +from py4DSTEM import Calibration import numpy as np -from os.path import join +from os import mkdir, remove, rmdir +from os.path import join, exists -# set filepath -path = py4DSTEM._TESTPATH + "/io_test_data/small_dm3_3Dstack.dm3" +# set filepaths +path_datacube = join(py4DSTEM._TESTPATH, "small_datacube.dm4") +path_3Darray = join(py4DSTEM._TESTPATH, "io_test_data/small_dm3_3Dstack.dm3") +path_out_dir = join(py4DSTEM._TESTPATH, "test_outputs") +path_out = join(path_out_dir, "test_calibration.h5") -class TestDataCube: +class TestCalibration: + + # setup - # setup/teardown def setup_class(cls): + if not exists(path_out_dir): + mkdir(path_out_dir) + + def teardown_class(cls): + if exists(path_out_dir): + rmdir(path_out_dir) + + def teardown_method(self): + if exists(path_out): + remove(path_out) + + + # test + + def test_imported_datacube_calibration(self): + + datacube = py4DSTEM.import_file(path_datacube) + + assert(hasattr(datacube,'calibration')) + assert(isinstance(datacube.calibration,Calibration)) + assert(hasattr(datacube,'root')) + assert(isinstance(datacube.root,py4DSTEM.Root)) + + + def test_instantiated_datacube_calibration(self): - # Read sim Au datacube - datacube = py4DSTEM.import_file(path) datacube = py4DSTEM.DataCube( - data=datacube.data.reshape((10,10,512,512)) + data = np.ones((4,8,128,128)) ) - cls.datacube = datacube - # tests + assert(hasattr(datacube,'calibration')) + assert(isinstance(datacube.calibration,Calibration)) + assert(hasattr(datacube,'root')) + assert(isinstance(datacube.root,py4DSTEM.Root)) + + datacube.calibration.set_Q_pixel_size(10) + + py4DSTEM.save( + path_out, + datacube + ) - def test_binning_default_dtype(self): + new_datacube = py4DSTEM.read(path_out) - dtype = self.datacube.data.dtype - assert(dtype == np.uint16) + assert(hasattr(new_datacube,'calibration')) + assert(isinstance(new_datacube.calibration,Calibration)) + assert(hasattr(new_datacube,'root')) + assert(isinstance(new_datacube.root,py4DSTEM.Root)) - self.datacube.bin_Q(2) + assert(new_datacube.calibration.get_Q_pixel_size() == 10) - assert(self.datacube.data.dtype == dtype) - new_dtype = np.uint32 - self.datacube.bin_Q(2, dtype=new_dtype) - assert(self.datacube.data.dtype == new_dtype) - assert(self.datacube.data.dtype != dtype) - pass diff --git a/test/test_datacube.py b/test/test_datacube.py index f95ecdbfd..7e0f29188 100644 --- a/test/test_datacube.py +++ b/test/test_datacube.py @@ -3,7 +3,7 @@ from os.path import join # set filepath -path = py4DSTEM._TESTPATH + "/io_test_data/small_dm3_3Dstack.dm3" +path = py4DSTEM._TESTPATH + "/small_datacube.dm4" @@ -12,11 +12,8 @@ class TestDataCube: # setup/teardown def setup_class(cls): - # Read sim Au datacube + # Read datacube datacube = py4DSTEM.import_file(path) - datacube = py4DSTEM.DataCube( - data=datacube.data.reshape((10,10,512,512)) - ) cls.datacube = datacube # tests diff --git a/test/test_nonnative_io/test_dm.py b/test/test_nonnative_io/test_dm.py index 18bab1fbd..9fd311579 100644 --- a/test/test_nonnative_io/test_dm.py +++ b/test/test_nonnative_io/test_dm.py @@ -4,15 +4,21 @@ # Set filepaths -filepath_dm = join(py4DSTEM._TESTPATH, "small_dm3.dm3") +filepath_dm4_datacube = join(py4DSTEM._TESTPATH, "small_datacube.dm4") +filepath_dm3_3Dstack = join(py4DSTEM._TESTPATH, "io_test_data/small_dm3_3Dstack.dm3") +def test_dmfile_datacube(): + data = py4DSTEM.import_file( filepath_dm4_datacube ) + assert isinstance(data, emdfile.Array) + assert isinstance(data, py4DSTEM.DataCube) + def test_dmfile_3Darray(): - data = py4DSTEM.import_file( filepath_dm ) + data = py4DSTEM.import_file( filepath_dm3_3Dstack ) assert isinstance(data, emdfile.Array) # TODO -# def test_dmfile_4Darray(): # def test_dmfile_multiple_datablocks(): +# def test_dmfile_2Darray From 5f1488d59661582b82021fc6d6b0e4f961a7b7cf Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 14:40:37 -0400 Subject: [PATCH 065/362] restructures data/classes mods --- py4DSTEM/__init__.py | 10 +- py4DSTEM/classes/__init__.py | 6 - py4DSTEM/classes/datacube.py | 248 ----------------- py4DSTEM/classes/methods/__init__.py | 1 - py4DSTEM/classes/probe.py | 2 +- py4DSTEM/classes/virtualdiffraction.py | 2 +- py4DSTEM/classes/virtualimage.py | 2 +- py4DSTEM/data/__init__.py | 9 + py4DSTEM/{classes => data}/calibration.py | 2 +- py4DSTEM/{classes => data}/data.py | 2 +- .../datacube_methods.py => data/datacube.py} | 250 +++++++++++++++++- py4DSTEM/data/datacube_methods.py | 4 + .../{classes => data}/diffractionslice.py | 2 +- .../propagating_calibration.py | 0 py4DSTEM/{classes => data}/qpoints.py | 2 +- py4DSTEM/{classes => data}/realslice.py | 2 +- py4DSTEM/io/filereaders/empad.py | 2 +- py4DSTEM/io/filereaders/read_K2.py | 2 +- py4DSTEM/io/filereaders/read_dm.py | 2 +- py4DSTEM/io/filereaders/read_mib.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_12.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_5.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_6.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_7.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_9.py | 2 +- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 8 +- py4DSTEM/process/calibration/origin.py | 2 +- py4DSTEM/process/classification/classutils.py | 2 +- py4DSTEM/process/diffraction/crystal_ACOM.py | 2 +- .../process/diskdetection/braggvectors.py | 2 +- .../process/diskdetection/diskdetection.py | 2 +- .../diskdetection/diskdetection_aiml.py | 2 +- .../diskdetection/diskdetection_aiml_cuda.py | 3 +- .../diskdetection/diskdetection_parallel.py | 2 +- .../diskdetection_parallel_new.py | 2 +- py4DSTEM/process/latticevectors/fit.py | 2 +- py4DSTEM/process/latticevectors/strain.py | 2 +- .../process/phase/iterative_base_class.py | 2 +- py4DSTEM/process/phase/iterative_dpc.py | 2 +- .../iterative_singleslice_ptychography.py | 2 +- py4DSTEM/process/polar/polar_datacube.py | 2 +- py4DSTEM/process/probe/probe.py | 3 +- py4DSTEM/process/virtualimage.py | 2 +- py4DSTEM/visualize/show.py | 2 +- py4DSTEM/visualize/virtualimage.py | 2 +- py4DSTEM/visualize/vis_special.py | 2 +- 46 files changed, 307 insertions(+), 305 deletions(-) delete mode 100644 py4DSTEM/classes/datacube.py create mode 100644 py4DSTEM/data/__init__.py rename py4DSTEM/{classes => data}/calibration.py (99%) rename py4DSTEM/{classes => data}/data.py (97%) rename py4DSTEM/{classes/methods/datacube_methods.py => data/datacube.py} (90%) create mode 100644 py4DSTEM/data/datacube_methods.py rename py4DSTEM/{classes => data}/diffractionslice.py (97%) rename py4DSTEM/{classes => data}/propagating_calibration.py (100%) rename py4DSTEM/{classes => data}/qpoints.py (97%) rename py4DSTEM/{classes => data}/realslice.py (97%) diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index dc4f765ae..f01604896 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -14,17 +14,19 @@ ) # processing classes -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, - VirtualDiffraction, - VirtualImage, - Probe, QPoints, Calibration, Data, ) +from py4DSTEM.classes import ( + VirtualDiffraction, + VirtualImage, + Probe, +) from py4DSTEM.process.diskdetection import ( BraggVectors, BraggVectorMap, diff --git a/py4DSTEM/classes/__init__.py b/py4DSTEM/classes/__init__.py index 27ea3e353..d97b413d9 100644 --- a/py4DSTEM/classes/__init__.py +++ b/py4DSTEM/classes/__init__.py @@ -1,13 +1,7 @@ _emd_hook = True -from py4DSTEM.classes.calibration import Calibration -from py4DSTEM.classes.data import Data -from py4DSTEM.classes.datacube import DataCube -from py4DSTEM.classes.diffractionslice import DiffractionSlice -from py4DSTEM.classes.realslice import RealSlice from py4DSTEM.classes.probe import Probe from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction from py4DSTEM.classes.virtualimage import VirtualImage -from py4DSTEM.classes.qpoints import QPoints diff --git a/py4DSTEM/classes/datacube.py b/py4DSTEM/classes/datacube.py deleted file mode 100644 index 964a89ff0..000000000 --- a/py4DSTEM/classes/datacube.py +++ /dev/null @@ -1,248 +0,0 @@ -# Defines the DataCube class, which stores 4D-STEM datacubes - -from typing import Optional,Union -import numpy as np - -from emdfile import Array,Root -from py4DSTEM.classes import Data, Calibration -from py4DSTEM.classes.methods import DataCubeMethods - -class DataCube(Array,Data,DataCubeMethods): - """ - Storage and processing methods for 4D-STEM datasets. - """ - - def __init__( - self, - data: np.ndarray, - name: Optional[str] = 'datacube', - slicelabels: Optional[Union[bool,list]] = None, - setup_tree: Optional[bool] = True, - calibration: Optional[Union[Calibration,None]] = None, - ): - """ - Accepts: - data (np.ndarray): the data - name (str): the name of the datacube - calibration (None or Calibration or 'pass'): default (None) - creates and attaches a new Calibration instance to root - metadata, or, passing a Calibration instance uses this instead. - 'skip' is for internal use for the reader - slicelabels (None or list): names for slices if this is a - stack of datacubes - - Returns: - A new DataCube instance. - """ - - # initialize DataCubeMethods - super(DataCubeMethods).__init__() - - # initialize as an Array - Array.__init__( - self, - data = data, - name = name, - units = 'pixel intensity', - dim_names = [ - 'Rx', - 'Ry', - 'Qx', - 'Qy' - ], - slicelabels = slicelabels - ) - - # initialize as Data - Data.__init__( - self, - setup_tree, - calibration - ) - - # cartesian coords - # TODO - tmp hack, needs to be refactored - - # this will break when preprocess methods are called - self.qyy,self.qxx = np.meshgrid( - np.arange(0,self.Q_Ny), - np.arange(0,self.Q_Nx) - ) - - # polar coords - self.polar = None - - - - def _setup_calibration(self, cal): - """ - Ensures that a calibration instance exists. Passing None - makes a new Calibration instance, puts it in root.calibration, and - makes a two way link. Passing a Calibration instance attaches that - instance. `'skip'` does nothing (internal use, on read from file). - """ - if cal is None: - self.calibration = Calibration( datacube = self ) - elif cal == 'skip': - pass - else: - assert(isinstance(cal, Calibration)), "`calibration` must be a Calibration instance, not type f{type(cal)}" - self.calibration = cal - cal._datacube = self - - - def copy(self): - """ - Copys datacube - """ - from py4DSTEM import DataCube - new_datacube = DataCube( - data = self.data.copy(), - name = self.name, - calibration = self.calibration.copy(), - slicelabels = self.slicelabels, - ) - - Qpixsize = new_datacube.calibration.get_Q_pixel_size() - Qpixunits = new_datacube.calibration.get_Q_pixel_units() - Rpixsize = new_datacube.calibration.get_R_pixel_size() - Rpixunits = new_datacube.calibration.get_R_pixel_units() - - new_datacube.set_dim( - 0, - [0,Rpixsize], - units = Rpixunits, - name = 'Rx' - ) - new_datacube.set_dim( - 1, - [0,Rpixsize], - units = Rpixunits, - name = 'Ry' - ) - - new_datacube.set_dim( - 2, - [0,Qpixsize], - units = Qpixunits, - name = 'Qx' - ) - new_datacube.set_dim( - 3, - [0,Qpixsize], - units = Qpixunits, - name = 'Qy' - ) - - return new_datacube - - - # properties - - - ## pixel size / units - - # Q - @property - def Q_pixel_size(self): - return self.calibration.get_Q_pixel_size() - @property - def Q_pixel_units(self): - return self.calibration.get_Q_pixel_units() - - # R - @property - def R_pixel_size(self): - return self.calibration.get_R_pixel_size() - @property - def R_pixel_units(self): - return self.calibration.get_R_pixel_units() - - # aliases - qpixsize = Q_pixel_size - qpixunit = Q_pixel_units - rpixsize = R_pixel_size - rpixunit = R_pixel_units - - - ## shape - - # FOV - @property - def R_Nx(self): - return self.data.shape[0] - @property - def R_Ny(self): - return self.data.shape[1] - @property - def Q_Nx(self): - return self.data.shape[2] - @property - def Q_Ny(self): - return self.data.shape[3] - - @property - def Rshape(self): - return (self.data.shape[0],self.data.shape[1]) - @property - def Qshape(self): - return (self.data.shape[2],self.data.shape[3]) - - @property - def R_N(self): - return self.R_Nx*self.R_Ny - - # aliases - qnx = Q_Nx - qny = Q_Ny - rnx = R_Nx - rny = R_Ny - rshape = Rshape - qshape = Qshape - rn = R_N - - - - - - # HDF5 i/o - - # to_h5 is inherited from Array - - # read - @classmethod - def _get_constructor_args(cls,group): - """ Construct a datacube with no calibration / metadata - """ - # We only need some of the Array constructors; - # dim vector/units are passed through when Calibration - # is loaded, and the runtim dim vectors are then set - # in _add_root_links - ar_args = Array._get_constructor_args(group) - - args = { - 'data': ar_args['data'], - 'name': ar_args['name'], - 'slicelabels': ar_args['slicelabels'], - 'calibration': 'skip' - } - - return args - - - def _add_root_links(self,group): - """ When reading from file, link to calibration metadata, - then use it to populate the datacube dim vectors - """ - # Link to the datacube - self.calibration._datacube = self - - # Populate dim vectors - self.calibration.set_Q_pixel_size( self.calibration.get_Q_pixel_size() ) - self.calibration.set_R_pixel_size( self.calibration.get_R_pixel_size() ) - self.calibration.set_Q_pixel_units( self.calibration.get_Q_pixel_units() ) - self.calibration.set_R_pixel_units( self.calibration.get_R_pixel_units() ) - - return - - - diff --git a/py4DSTEM/classes/methods/__init__.py b/py4DSTEM/classes/methods/__init__.py index ab06bce4e..a2455dba3 100644 --- a/py4DSTEM/classes/methods/__init__.py +++ b/py4DSTEM/classes/methods/__init__.py @@ -1,3 +1,2 @@ -from py4DSTEM.classes.methods.datacube_methods import DataCubeMethods from py4DSTEM.classes.methods.probe_methods import ProbeMethods diff --git a/py4DSTEM/classes/probe.py b/py4DSTEM/classes/probe.py index fc6dade97..53eaa3298 100644 --- a/py4DSTEM/classes/probe.py +++ b/py4DSTEM/classes/probe.py @@ -1,5 +1,5 @@ -from py4DSTEM.classes import DiffractionSlice, Data +from py4DSTEM.data import DiffractionSlice, Data from py4DSTEM.classes.methods import ProbeMethods from typing import Optional diff --git a/py4DSTEM/classes/virtualdiffraction.py b/py4DSTEM/classes/virtualdiffraction.py index 9d1bb4317..3831bbefe 100644 --- a/py4DSTEM/classes/virtualdiffraction.py +++ b/py4DSTEM/classes/virtualdiffraction.py @@ -2,7 +2,7 @@ from typing import Optional import numpy as np -from py4DSTEM.classes import DiffractionSlice,Data +from py4DSTEM.data import DiffractionSlice,Data diff --git a/py4DSTEM/classes/virtualimage.py b/py4DSTEM/classes/virtualimage.py index a14d83e99..8a9bf8c9e 100644 --- a/py4DSTEM/classes/virtualimage.py +++ b/py4DSTEM/classes/virtualimage.py @@ -2,7 +2,7 @@ from typing import Optional import numpy as np -from py4DSTEM.classes import RealSlice,Data +from py4DSTEM.data import RealSlice,Data diff --git a/py4DSTEM/data/__init__.py b/py4DSTEM/data/__init__.py new file mode 100644 index 000000000..f8cd284e5 --- /dev/null +++ b/py4DSTEM/data/__init__.py @@ -0,0 +1,9 @@ +_emd_hook = True + +from py4DSTEM.data.calibration import Calibration +from py4DSTEM.data.data import Data +from py4DSTEM.data.datacube import DataCube +from py4DSTEM.data.diffractionslice import DiffractionSlice +from py4DSTEM.data.realslice import RealSlice +from py4DSTEM.data.qpoints import QPoints + diff --git a/py4DSTEM/classes/calibration.py b/py4DSTEM/data/calibration.py similarity index 99% rename from py4DSTEM/classes/calibration.py rename to py4DSTEM/data/calibration.py index dbeef3e2b..e96d61e8b 100644 --- a/py4DSTEM/classes/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -5,7 +5,7 @@ from typing import Optional from emdfile import Metadata -from py4DSTEM.classes.propagating_calibration import propagating_calibration +from py4DSTEM.data.propagating_calibration import propagating_calibration class Calibration(Metadata): """ diff --git a/py4DSTEM/classes/data.py b/py4DSTEM/data/data.py similarity index 97% rename from py4DSTEM/classes/data.py rename to py4DSTEM/data/data.py index 5794b9963..0f6d10d52 100644 --- a/py4DSTEM/classes/data.py +++ b/py4DSTEM/data/data.py @@ -4,7 +4,7 @@ import warnings from emdfile import Node, Root -from py4DSTEM.classes import Calibration +from py4DSTEM.data import Calibration class Data: diff --git a/py4DSTEM/classes/methods/datacube_methods.py b/py4DSTEM/data/datacube.py similarity index 90% rename from py4DSTEM/classes/methods/datacube_methods.py rename to py4DSTEM/data/datacube.py index bf347e5ae..514424c1d 100644 --- a/py4DSTEM/classes/methods/datacube_methods.py +++ b/py4DSTEM/data/datacube.py @@ -1,18 +1,258 @@ -# Functions to become DataCube methods +# Defines the DataCube class, which stores 4D-STEM datacubes import numpy as np from scipy.ndimage import distance_transform_edt, binary_fill_holes, gaussian_filter1d from scipy.interpolate import interp1d +from typing import Optional,Union -from emdfile import Array, Metadata, Node +from emdfile import Array, Metadata, Node, Root +from py4DSTEM.data import Data, Calibration -class DataCubeMethods: + +class DataCube(Array,Data): """ - A container for DataCube object instance methods. + Storage and processing methods for 4D-STEM datasets. """ + def __init__( + self, + data: np.ndarray, + name: Optional[str] = 'datacube', + slicelabels: Optional[Union[bool,list]] = None, + setup_tree: Optional[bool] = True, + calibration: Optional[Union[Calibration,None]] = None, + ): + """ + Accepts: + data (np.ndarray): the data + name (str): the name of the datacube + calibration (None or Calibration or 'pass'): default (None) + creates and attaches a new Calibration instance to root + metadata, or, passing a Calibration instance uses this instead. + 'skip' is for internal use for the reader + slicelabels (None or list): names for slices if this is a + stack of datacubes + + Returns: + A new DataCube instance. + """ + + # initialize DataCubeMethods + super(DataCubeMethods).__init__() + + # initialize as an Array + Array.__init__( + self, + data = data, + name = name, + units = 'pixel intensity', + dim_names = [ + 'Rx', + 'Ry', + 'Qx', + 'Qy' + ], + slicelabels = slicelabels + ) + + # initialize as Data + Data.__init__( + self, + setup_tree, + calibration + ) + + # cartesian coords + # TODO - tmp hack, needs to be refactored - + # this will break when preprocess methods are called + self.qyy,self.qxx = np.meshgrid( + np.arange(0,self.Q_Ny), + np.arange(0,self.Q_Nx) + ) + + # polar coords + self.polar = None + + + + def _setup_calibration(self, cal): + """ + Ensures that a calibration instance exists. Passing None + makes a new Calibration instance, puts it in root.calibration, and + makes a two way link. Passing a Calibration instance attaches that + instance. `'skip'` does nothing (internal use, on read from file). + """ + if cal is None: + self.calibration = Calibration( datacube = self ) + elif cal == 'skip': + pass + else: + assert(isinstance(cal, Calibration)), "`calibration` must be a Calibration instance, not type f{type(cal)}" + self.calibration = cal + cal._datacube = self + + + def copy(self): + """ + Copys datacube + """ + from py4DSTEM import DataCube + new_datacube = DataCube( + data = self.data.copy(), + name = self.name, + calibration = self.calibration.copy(), + slicelabels = self.slicelabels, + ) + + Qpixsize = new_datacube.calibration.get_Q_pixel_size() + Qpixunits = new_datacube.calibration.get_Q_pixel_units() + Rpixsize = new_datacube.calibration.get_R_pixel_size() + Rpixunits = new_datacube.calibration.get_R_pixel_units() + + new_datacube.set_dim( + 0, + [0,Rpixsize], + units = Rpixunits, + name = 'Rx' + ) + new_datacube.set_dim( + 1, + [0,Rpixsize], + units = Rpixunits, + name = 'Ry' + ) + + new_datacube.set_dim( + 2, + [0,Qpixsize], + units = Qpixunits, + name = 'Qx' + ) + new_datacube.set_dim( + 3, + [0,Qpixsize], + units = Qpixunits, + name = 'Qy' + ) + + return new_datacube + + + # properties + + + ## pixel size / units + + # Q + @property + def Q_pixel_size(self): + return self.calibration.get_Q_pixel_size() + @property + def Q_pixel_units(self): + return self.calibration.get_Q_pixel_units() + + # R + @property + def R_pixel_size(self): + return self.calibration.get_R_pixel_size() + @property + def R_pixel_units(self): + return self.calibration.get_R_pixel_units() + + # aliases + qpixsize = Q_pixel_size + qpixunit = Q_pixel_units + rpixsize = R_pixel_size + rpixunit = R_pixel_units + + + ## shape + + # FOV + @property + def R_Nx(self): + return self.data.shape[0] + @property + def R_Ny(self): + return self.data.shape[1] + @property + def Q_Nx(self): + return self.data.shape[2] + @property + def Q_Ny(self): + return self.data.shape[3] + + @property + def Rshape(self): + return (self.data.shape[0],self.data.shape[1]) + @property + def Qshape(self): + return (self.data.shape[2],self.data.shape[3]) + + @property + def R_N(self): + return self.R_Nx*self.R_Ny + + # aliases + qnx = Q_Nx + qny = Q_Ny + rnx = R_Nx + rny = R_Ny + rshape = Rshape + qshape = Qshape + rn = R_N + + + + + + # I/O + + # to_h5 is inherited from Array + + # read + @classmethod + def _get_constructor_args(cls,group): + """ Construct a datacube with no calibration / metadata + """ + # We only need some of the Array constructors; + # dim vector/units are passed through when Calibration + # is loaded, and the runtim dim vectors are then set + # in _add_root_links + ar_args = Array._get_constructor_args(group) + + args = { + 'data': ar_args['data'], + 'name': ar_args['name'], + 'slicelabels': ar_args['slicelabels'], + 'calibration': 'skip' + } + + return args + + + def _add_root_links(self,group): + """ When reading from file, link to calibration metadata, + then use it to populate the datacube dim vectors + """ + # Link to the datacube + self.calibration._datacube = self + + # Populate dim vectors + self.calibration.set_Q_pixel_size( self.calibration.get_Q_pixel_size() ) + self.calibration.set_R_pixel_size( self.calibration.get_R_pixel_size() ) + self.calibration.set_Q_pixel_units( self.calibration.get_Q_pixel_units() ) + self.calibration.set_R_pixel_units( self.calibration.get_R_pixel_units() ) + + return + + + + + # Class methods + def add( self, data, @@ -1667,5 +1907,3 @@ def get_braggmask( - - diff --git a/py4DSTEM/data/datacube_methods.py b/py4DSTEM/data/datacube_methods.py new file mode 100644 index 000000000..fd40910d9 --- /dev/null +++ b/py4DSTEM/data/datacube_methods.py @@ -0,0 +1,4 @@ + + + + diff --git a/py4DSTEM/classes/diffractionslice.py b/py4DSTEM/data/diffractionslice.py similarity index 97% rename from py4DSTEM/classes/diffractionslice.py rename to py4DSTEM/data/diffractionslice.py index 9f75dc43d..ece658adc 100644 --- a/py4DSTEM/classes/diffractionslice.py +++ b/py4DSTEM/data/diffractionslice.py @@ -2,7 +2,7 @@ # diffraction-shaped data from emdfile import Array -from py4DSTEM.classes import Data +from py4DSTEM.data import Data from typing import Optional,Union import numpy as np diff --git a/py4DSTEM/classes/propagating_calibration.py b/py4DSTEM/data/propagating_calibration.py similarity index 100% rename from py4DSTEM/classes/propagating_calibration.py rename to py4DSTEM/data/propagating_calibration.py diff --git a/py4DSTEM/classes/qpoints.py b/py4DSTEM/data/qpoints.py similarity index 97% rename from py4DSTEM/classes/qpoints.py rename to py4DSTEM/data/qpoints.py index 62788f518..c29127406 100644 --- a/py4DSTEM/classes/qpoints.py +++ b/py4DSTEM/data/qpoints.py @@ -1,7 +1,7 @@ # Defines the QPoints class, which stores PointLists with fields 'qx','qy','intensity' from emdfile import PointList -from py4DSTEM.classes import Data +from py4DSTEM.data import Data from typing import Optional import numpy as np diff --git a/py4DSTEM/classes/realslice.py b/py4DSTEM/data/realslice.py similarity index 97% rename from py4DSTEM/classes/realslice.py rename to py4DSTEM/data/realslice.py index 1a75f1e8e..0a2f893c9 100644 --- a/py4DSTEM/classes/realslice.py +++ b/py4DSTEM/data/realslice.py @@ -1,7 +1,7 @@ # Defines the RealSlice class, which stores 2(+1)D real-space shaped data from emdfile import Array -from py4DSTEM.classes import Data +from py4DSTEM.data import Data from typing import Optional,Union import numpy as np diff --git a/py4DSTEM/io/filereaders/empad.py b/py4DSTEM/io/filereaders/empad.py index 04feaee11..4aef6ee77 100644 --- a/py4DSTEM/io/filereaders/empad.py +++ b/py4DSTEM/io/filereaders/empad.py @@ -8,7 +8,7 @@ import numpy as np from pathlib import Path from emdfile import tqdmnd -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from py4DSTEM.preprocess.utils import bin2D diff --git a/py4DSTEM/io/filereaders/read_K2.py b/py4DSTEM/io/filereaders/read_K2.py index 2e483e294..cf5dd8be6 100644 --- a/py4DSTEM/io/filereaders/read_K2.py +++ b/py4DSTEM/io/filereaders/read_K2.py @@ -9,7 +9,7 @@ except ImportError: pass from emdfile import tqdmnd -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube def read_gatan_K2_bin(fp, mem="MEMMAP", binfactor=1, metadata=False, **kwargs): diff --git a/py4DSTEM/io/filereaders/read_dm.py b/py4DSTEM/io/filereaders/read_dm.py index 60b8975c9..6762ab9f8 100644 --- a/py4DSTEM/io/filereaders/read_dm.py +++ b/py4DSTEM/io/filereaders/read_dm.py @@ -5,7 +5,7 @@ from ncempy.io import dm from emdfile import tqdmnd, Array -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from py4DSTEM.preprocess.utils import bin2D diff --git a/py4DSTEM/io/filereaders/read_mib.py b/py4DSTEM/io/filereaders/read_mib.py index cfb0b10b8..b8e42ee4f 100644 --- a/py4DSTEM/io/filereaders/read_mib.py +++ b/py4DSTEM/io/filereaders/read_mib.py @@ -3,7 +3,7 @@ # Based on the PyXEM load_mib module https://github.com/pyxem/pyxem/blob/563a3bb5f3233f46cd3e57f3cd6f9ddf7af55ad0/pyxem/utils/io_utils.py import numpy as np -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube import os def load_mib( diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_12.py b/py4DSTEM/io/legacy/legacy12/read_v0_12.py index a327a567b..9622f0a0e 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_12.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_12.py @@ -9,7 +9,7 @@ PointList, PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_5.py b/py4DSTEM/io/legacy/legacy12/read_v0_5.py index 109c0a4c3..fa53fb7cb 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_5.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_5.py @@ -9,7 +9,7 @@ PointList, PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_6.py b/py4DSTEM/io/legacy/legacy12/read_v0_6.py index ded73a8c4..bec2e6d69 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_6.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_6.py @@ -9,7 +9,7 @@ PointList, PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_7.py b/py4DSTEM/io/legacy/legacy12/read_v0_7.py index 7635c56f6..7e3b782df 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_7.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_7.py @@ -9,7 +9,7 @@ PointList, PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_9.py b/py4DSTEM/io/legacy/legacy12/read_v0_9.py index b3fe4583b..71bf7adaf 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_9.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_9.py @@ -9,7 +9,7 @@ PointList, PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, DiffractionSlice, RealSlice, diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 1b0deafaa..453c4cf1c 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -36,15 +36,17 @@ PointListArray ) -from py4DSTEM.classes import ( +from py4DSTEM.data import ( Calibration, DataCube, DiffractionSlice, - VirtualDiffraction, RealSlice, + QPoints, +) +from py4DSTEM.classes import ( VirtualImage, + VirtualDiffraction, Probe, - QPoints, ) from py4DSTEM.process.diskdetection.braggvectors import BraggVectors diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index bc8c0be0c..5a4b09803 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -6,7 +6,7 @@ from scipy.optimize import leastsq from emdfile import tqdmnd, PointListArray -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from py4DSTEM.process.calibration.probe import get_probe_size from py4DSTEM.process.fit import plane,parabola,bezier_two,fit_2D from py4DSTEM.process.utils import get_CoM, add_to_2D_array_from_floats, get_maxima_2D diff --git a/py4DSTEM/process/classification/classutils.py b/py4DSTEM/process/classification/classutils.py index 1a7bccfda..b2381c26f 100644 --- a/py4DSTEM/process/classification/classutils.py +++ b/py4DSTEM/process/classification/classutils.py @@ -3,7 +3,7 @@ import numpy as np from emdfile import tqdmnd, PointListArray -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from py4DSTEM.process.utils import get_shifted_ar def get_class_DP(datacube, class_image, thresh=0.01, xshifts=None, yshifts=None, diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index b303ee916..4299a3624 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -4,7 +4,7 @@ from typing import Union, Optional from emdfile import tqdmnd, PointList, PointListArray -from py4DSTEM.classes import RealSlice +from py4DSTEM.data import RealSlice from py4DSTEM.process.diffraction.utils import Orientation, OrientationMap, axisEqual3D from py4DSTEM.process.utils import electron_wavelength_angstrom diff --git a/py4DSTEM/process/diskdetection/braggvectors.py b/py4DSTEM/process/diskdetection/braggvectors.py index 3a22bd27b..3130e2c76 100644 --- a/py4DSTEM/process/diskdetection/braggvectors.py +++ b/py4DSTEM/process/diskdetection/braggvectors.py @@ -1,6 +1,6 @@ # Defines the BraggVectors class -from py4DSTEM.classes import Data +from py4DSTEM.data import Data from emdfile import Custom,PointListArray,PointList,Metadata from py4DSTEM.process.diskdetection.braggvector_methods import BraggVectorMethods from os.path import basename diff --git a/py4DSTEM/process/diskdetection/diskdetection.py b/py4DSTEM/process/diskdetection/diskdetection.py index 1674fdc93..1c7916a51 100644 --- a/py4DSTEM/process/diskdetection/diskdetection.py +++ b/py4DSTEM/process/diskdetection/diskdetection.py @@ -6,7 +6,7 @@ from emdfile import tqdmnd from py4DSTEM.process.diskdetection.braggvectors import BraggVectors -from py4DSTEM.classes import DataCube, QPoints +from py4DSTEM.data import DataCube, QPoints from py4DSTEM.preprocess.utils import get_maxima_2D from py4DSTEM.process.utils.cross_correlate import get_cross_correlation_FT from py4DSTEM.process.diskdetection.diskdetection_aiml import find_Bragg_disks_aiml diff --git a/py4DSTEM/process/diskdetection/diskdetection_aiml.py b/py4DSTEM/process/diskdetection/diskdetection_aiml.py index e076e0732..8f82dce9a 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_aiml.py +++ b/py4DSTEM/process/diskdetection/diskdetection_aiml.py @@ -15,7 +15,7 @@ from emdfile import tqdmnd, PointList, PointListArray from py4DSTEM.process.diskdetection.braggvectors import BraggVectors -from py4DSTEM.classes import QPoints +from py4DSTEM.data import QPoints from py4DSTEM.process.utils import get_maxima_2D # from py4DSTEM.process.diskdetection import universal_threshold diff --git a/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py b/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py index 1b6c38565..fbc9339a0 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py +++ b/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py @@ -8,7 +8,8 @@ from emdfile import tqdmnd from py4DSTEM.process.diskdetection.braggvectors import BraggVectors -from py4DSTEM.classes import PointList, PointListArray, QPoints +from emdfile import PointList, PointListArray +from py4DSTEM.data import QPoints from py4DSTEM.process.diskdetection.kernels import kernels from py4DSTEM.process.diskdetection.diskdetection_aiml import _get_latest_model # from py4DSTEM.process.diskdetection.diskdetection import universal_threshold diff --git a/py4DSTEM/process/diskdetection/diskdetection_parallel.py b/py4DSTEM/process/diskdetection/diskdetection_parallel.py index f6d2624e1..5a6d6dc11 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_parallel.py +++ b/py4DSTEM/process/diskdetection/diskdetection_parallel.py @@ -9,7 +9,7 @@ # local import py4DSTEM -from py4DSTEM.classes import PointListArray +from emdfile import PointListArray def _find_Bragg_disks_single_DP_FK(DP, probe_kernel_FT, diff --git a/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py b/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py index c9e224eee..af011cb8e 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py +++ b/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py @@ -17,7 +17,7 @@ import distributed import py4DSTEM -from py4DSTEM.classes import PointListArray, PointList +from emdfile import PointListArray, PointList from py4DSTEM.process.diskdetection.diskdetection import _find_Bragg_disks_single_DP_FK diff --git a/py4DSTEM/process/latticevectors/fit.py b/py4DSTEM/process/latticevectors/fit.py index dae5d485f..822ffdea5 100644 --- a/py4DSTEM/process/latticevectors/fit.py +++ b/py4DSTEM/process/latticevectors/fit.py @@ -4,7 +4,7 @@ from numpy.linalg import lstsq from emdfile import tqdmnd, PointList, PointListArray -from py4DSTEM.classes import RealSlice +from py4DSTEM.data import RealSlice def fit_lattice_vectors(braggpeaks, x0=0, y0=0, minNumPeaks=5): """ diff --git a/py4DSTEM/process/latticevectors/strain.py b/py4DSTEM/process/latticevectors/strain.py index 0521f703c..50b9bddc9 100644 --- a/py4DSTEM/process/latticevectors/strain.py +++ b/py4DSTEM/process/latticevectors/strain.py @@ -3,7 +3,7 @@ import numpy as np from numpy.linalg import lstsq -from py4DSTEM.classes import RealSlice +from py4DSTEM.data import RealSlice def get_reference_g1g2(g1g2_map, mask): """ diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index c2acbee34..42e207d97 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -18,7 +18,7 @@ cp = None from emdfile import Array, Custom, Metadata, _read_metadata, tqdmnd -from py4DSTEM.classes import Calibration, DataCube +from py4DSTEM.data import Calibration, DataCube from py4DSTEM.process.calibration import fit_origin from py4DSTEM.process.phase.iterative_ptychographic_constraints import ( PtychographicConstraints, diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index b2d8ef891..16381c4d8 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -17,7 +17,7 @@ cp = None from emdfile import Array, Custom, Metadata, _read_metadata, tqdmnd -from py4DSTEM.classes import Calibration, DataCube +from py4DSTEM.data import Calibration, DataCube from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction warnings.simplefilter(action="always", category=UserWarning) diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 8a83fa5ba..ce298967d 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -18,7 +18,7 @@ cp = None from emdfile import Custom, tqdmnd -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from py4DSTEM.process.phase.iterative_base_class import PtychographicReconstruction from py4DSTEM.process.phase.utils import ( ComplexProbe, diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index c8afa7609..9aa93d678 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -1,5 +1,5 @@ import numpy as np -from py4DSTEM.classes import DataCube +from py4DSTEM.data import DataCube from scipy.ndimage import binary_opening,binary_closing, gaussian_filter1d diff --git a/py4DSTEM/process/probe/probe.py b/py4DSTEM/process/probe/probe.py index c9bb98634..04a2926de 100644 --- a/py4DSTEM/process/probe/probe.py +++ b/py4DSTEM/process/probe/probe.py @@ -5,7 +5,8 @@ binary_opening, binary_dilation, distance_transform_edt) from emdfile import tqdmnd -from py4DSTEM.classes import DataCube, Probe +from py4DSTEM.data import DataCube +from py4DSTEM.classes import Probe from py4DSTEM.process.utils import get_shifted_ar, get_shift diff --git a/py4DSTEM/process/virtualimage.py b/py4DSTEM/process/virtualimage.py index 1c5e5e1da..d6fe79566 100644 --- a/py4DSTEM/process/virtualimage.py +++ b/py4DSTEM/process/virtualimage.py @@ -2,7 +2,7 @@ import numpy as np import dask.array as da from emdfile import tqdmnd -from py4DSTEM.classes import Calibration +from py4DSTEM.data import Calibration def get_virtual_image( datacube, diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 45a5b7395..448a44590 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -9,7 +9,7 @@ from math import log from copy import copy -from py4DSTEM.classes import ( +from py4DSTEM.data import ( Calibration, DiffractionSlice, RealSlice diff --git a/py4DSTEM/visualize/virtualimage.py b/py4DSTEM/visualize/virtualimage.py index 87931bfba..830fde5c5 100644 --- a/py4DSTEM/visualize/virtualimage.py +++ b/py4DSTEM/visualize/virtualimage.py @@ -1,6 +1,6 @@ import numpy as np -from py4DSTEM.classes import Calibration, DataCube, DiffractionSlice +from py4DSTEM.data import Calibration, DataCube, DiffractionSlice from py4DSTEM.visualize.show import show diff --git a/py4DSTEM/visualize/vis_special.py b/py4DSTEM/visualize/vis_special.py index af8c074d0..d6ce64cf5 100644 --- a/py4DSTEM/visualize/vis_special.py +++ b/py4DSTEM/visualize/vis_special.py @@ -6,7 +6,7 @@ from scipy.spatial import Voronoi from emdfile import PointList -from py4DSTEM.classes import DataCube,Calibration +from py4DSTEM.data import DataCube,Calibration from py4DSTEM.process.utils import get_voronoi_vertices,convert_ellipse_params from py4DSTEM.process.calibration import double_sided_gaussian from py4DSTEM.process.latticevectors import get_selected_lattice_vectors From a99aba0dfe71620258c7817003cd3d1b0c3b968f Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 17:19:39 -0400 Subject: [PATCH 066/362] bumps emdfile to 0.0.10 --- py4DSTEM/data/datacube.py | 4 ---- setup.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/py4DSTEM/data/datacube.py b/py4DSTEM/data/datacube.py index 514424c1d..c573b7e30 100644 --- a/py4DSTEM/data/datacube.py +++ b/py4DSTEM/data/datacube.py @@ -38,10 +38,6 @@ def __init__( Returns: A new DataCube instance. """ - - # initialize DataCubeMethods - super(DataCubeMethods).__init__() - # initialize as an Array Array.__init__( self, diff --git a/setup.py b/setup.py index 2f1e15a63..f518599cc 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ 'gdown >= 4.4.0', 'dask >= 2.3.0', 'distributed >= 2.3.0', - 'emdfile >= 0.0.9', + 'emdfile >= 0.0.10', ], extras_require={ 'ipyparallel': ['ipyparallel >= 6.2.4', 'dill >= 0.3.3'], From a7f393f0baf6785d2abae4d046ce7f7c3fbf277e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 22 Jun 2023 17:20:35 -0400 Subject: [PATCH 067/362] rms datacube_methods --- py4DSTEM/data/datacube_methods.py | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 py4DSTEM/data/datacube_methods.py diff --git a/py4DSTEM/data/datacube_methods.py b/py4DSTEM/data/datacube_methods.py deleted file mode 100644 index fd40910d9..000000000 --- a/py4DSTEM/data/datacube_methods.py +++ /dev/null @@ -1,4 +0,0 @@ - - - - From df5cfe95eed6cf7b0f5a6ae35949217b4e3b3767 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:18:58 -0400 Subject: [PATCH 068/362] propagate sampling overrides --- .../iterative_mixedstate_ptychography.py | 22 +++++++++++++- .../iterative_multislice_ptychography.py | 22 +++++++++++++- .../iterative_overlap_magnetic_tomography.py | 23 ++++++++++++++- .../phase/iterative_overlap_tomography.py | 23 ++++++++++++++- .../iterative_simultaneous_ptychography.py | 29 ++++++++++++++++++- .../iterative_singleslice_ptychography.py | 14 +++++---- 6 files changed, 122 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index afa565871..4dea8172f 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -52,7 +52,9 @@ class MixedstatePtychographicReconstruction(PtychographicReconstruction): num_probes: int, optional Number of mixed-state probes semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -91,6 +93,7 @@ def __init__( datacube: DataCube = None, num_probes: int = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -171,6 +174,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -196,6 +200,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -245,6 +252,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -289,6 +302,9 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -344,6 +360,10 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a67bd93e9..a9dcf2d41 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -56,7 +56,9 @@ class MultislicePtychographicReconstruction(PtychographicReconstruction): datacube: DataCube, optional Input 4D diffraction pattern intensities semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -99,6 +101,7 @@ def __init__( slice_thicknesses: Union[float, Sequence[float]], datacube: DataCube = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -175,6 +178,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -271,6 +275,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -320,6 +327,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -364,6 +377,9 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -419,6 +435,10 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 92905cac2..30e2b520f 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -63,7 +63,9 @@ class OverlapMagneticTomographicReconstruction(PtychographicReconstruction): - \beta tilt around x-axis - -\alpha tilt around z-axis semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -106,6 +108,7 @@ def __init__( tilt_angles_deg: Sequence[Tuple[float, float]], datacube: Sequence[DataCube] = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -171,6 +174,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -422,6 +426,9 @@ def preprocess( diffraction_patterns_transpose: bool = None, force_com_shifts: Sequence[float] = None, progress_bar: bool = True, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -458,6 +465,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. One tuple per tilt. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -551,6 +564,9 @@ def preprocess( intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube[tilt_index], require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -600,6 +616,11 @@ def preprocess( self._scan_positions[tilt_index] ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6166640f4..a55a08697 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -58,7 +58,9 @@ class OverlapTomographicReconstruction(PtychographicReconstruction): tilt_angles_deg: Sequence[float] List of tilt angles in degrees, semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -101,6 +103,7 @@ def __init__( tilt_angles_deg: Sequence[float], datacube: Sequence[DataCube] = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -172,6 +175,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -331,6 +335,9 @@ def preprocess( diffraction_patterns_rotate_degrees: float = None, diffraction_patterns_transpose: bool = None, force_com_shifts: Sequence[float] = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, progress_bar: bool = True, object_fov_mask: np.ndarray = None, **kwargs, @@ -368,6 +375,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. One tuple per tilt. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -460,6 +473,9 @@ def preprocess( intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube[tilt_index], require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -509,6 +525,11 @@ def preprocess( self._scan_positions[tilt_index] ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index da358e089..ae302f660 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -53,7 +53,9 @@ class SimultaneousPtychographicReconstruction(PtychographicReconstruction): simultaneous_measurements_mode: str, optional One of '-+', '-0+', '0+', where -/0/+ refer to the sign of the magnetic potential semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -95,6 +97,7 @@ def __init__( datacube: Sequence[DataCube] = None, simultaneous_measurements_mode: str = "-+", semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -160,6 +163,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -184,6 +188,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -230,6 +237,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -344,6 +357,9 @@ def preprocess( intensities_0 = self._extract_intensities_and_calibrations_from_datacube( measurement_0, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -424,6 +440,9 @@ def preprocess( intensities_1 = self._extract_intensities_and_calibrations_from_datacube( measurement_1, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -505,6 +524,9 @@ def preprocess( intensities_2 = self._extract_intensities_and_calibrations_from_datacube( measurement_2, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -591,6 +613,11 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 0836b0ce2..c4c097f1b 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -50,7 +50,9 @@ class SingleslicePtychographicReconstruction(PtychographicReconstruction): datacube: DataCube Input 4D diffraction pattern intensities semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -289,11 +291,6 @@ def preprocess( force_reciprocal_sampling=force_reciprocal_sampling, ) - # handle semiangle specified in pixels - if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - - ( self._com_measured_x, self._com_measured_y, @@ -346,6 +343,11 @@ def preprocess( self._positions_px = self._calculate_scan_positions_in_pixels( self._scan_positions ) + + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] From 901da2395efb6b911ce1e3f3afedbde260aea654 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:21:25 -0400 Subject: [PATCH 069/362] format with black --- .../process/phase/iterative_base_class.py | 20 ++++++++++++------- .../iterative_mixedstate_ptychography.py | 4 +++- .../iterative_multislice_ptychography.py | 4 +++- .../iterative_overlap_magnetic_tomography.py | 5 +++-- .../phase/iterative_overlap_tomography.py | 5 +++-- .../iterative_simultaneous_ptychography.py | 5 +++-- .../iterative_singleslice_ptychography.py | 4 +++- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index dcd1d0d97..322de95bd 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -198,7 +198,7 @@ def _preprocess_datacube_and_vacuum_probe( output_size=diffraction_intensities_shape, force_nonnegative=True, ) - + if probe_roi_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = probe_roi_shape @@ -324,9 +324,9 @@ def _extract_intensities_and_calibrations_from_datacube( # there is no xor keyword in Python! angular = force_angular_sampling is not None reciprocal = force_reciprocal_sampling is not None - assert (angular and not reciprocal) or (not angular and reciprocal), ( - "Only one of angular or reciprocal calibration can be forced!" - ) + assert (angular and not reciprocal) or ( + not angular and reciprocal + ), "Only one of angular or reciprocal calibration can be forced!" # angular calibration specified if angular: @@ -335,7 +335,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._reciprocal_sampling = ( - force_angular_sampling / electron_wavelength_angstrom(self._energy) / 1e3, + force_angular_sampling + / electron_wavelength_angstrom(self._energy) + / 1e3, ) * 2 self._reciprocal_units = ("A^-1",) * 2 @@ -346,7 +348,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._angular_sampling = ( - force_reciprocal_sampling * electron_wavelength_angstrom(self._energy) * 1e3, + force_reciprocal_sampling + * electron_wavelength_angstrom(self._energy) + * 1e3, ) * 2 self._angular_units = ("mrad",) * 2 @@ -377,7 +381,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._angular_sampling = ( - reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, + reciprocal_size + * electron_wavelength_angstrom(self._energy) + * 1e3, ) * 2 self._angular_units = ("mrad",) * 2 diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 4dea8172f..8d4574aa4 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -362,7 +362,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a9dcf2d41..36b44b77e 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -437,7 +437,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 30e2b520f..7497183da 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -618,8 +618,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index a55a08697..82d1caac3 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -527,8 +527,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index ae302f660..9e4b39cf5 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -615,8 +615,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index c4c097f1b..6004b2a98 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -346,7 +346,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: From 76797a82672b62ad1c56b4c3ea04db5f62a9c8f9 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:45:10 -0400 Subject: [PATCH 070/362] first attempt at caching preprocessed object if not optimized --- py4DSTEM/process/phase/parameter_optimize.py | 30 ++++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 987ffedef..ee8473be1 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -294,17 +294,35 @@ def _get_optimization_function( dictionary are used. """ - # Construct partial methods to encapsulate the static parameters - obj = partial(cls, **init_static_args) - affine = partial(AffineTransform, **affine_static_args) - prep = partial(cls.preprocess, **preprocess_static_args) - recon = partial(cls.reconstruct, **reconstruct_static_args) - + # Get lists of optimization parameters for each step init_params = list(init_optimization_params.keys()) afft_params = list(affine_optimization_params.keys()) prep_params = list(preprocess_optimization_params.keys()) reco_params = list(reconstruct_optimization_params.keys()) + # Construct partial methods to encapsulate the static parameters. + # If only ``reconstruct`` has optimization variables, perform + # preprocessing now, store the ptycho object, and use dummy + # functions instead of the partials + if (len(init_params),len(afft_params),len(prep_params)) == (0,0,0): + affine_preprocessed = AffineTransform(**affine_static_args) + init_args = init_static_args.copy() + init_args["initial_scan_positions"] = self._get_scan_positions(affine_preprocessed, init_static_args["datacube"]) + + ptycho_preprocessed = cls.__init__(**init_args).preprocess(**preprocess_static_args) + + def obj(**kwargs): + return ptycho_preprocessed + def prep(ptycho,**kwargs): + return ptycho + + else: + obj = partial(cls, **init_static_args) + affine = partial(AffineTransform, **affine_static_args) + prep = partial(cls.preprocess, **preprocess_static_args) + + recon = partial(cls.reconstruct, **reconstruct_static_args) + # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) From abe8eab1056a1245634509b02b58c2c14f075c4c Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:45:32 -0400 Subject: [PATCH 071/362] format with black --- py4DSTEM/process/phase/parameter_optimize.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ee8473be1..292df27b6 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -304,16 +304,21 @@ def _get_optimization_function( # If only ``reconstruct`` has optimization variables, perform # preprocessing now, store the ptycho object, and use dummy # functions instead of the partials - if (len(init_params),len(afft_params),len(prep_params)) == (0,0,0): + if (len(init_params), len(afft_params), len(prep_params)) == (0, 0, 0): affine_preprocessed = AffineTransform(**affine_static_args) init_args = init_static_args.copy() - init_args["initial_scan_positions"] = self._get_scan_positions(affine_preprocessed, init_static_args["datacube"]) + init_args["initial_scan_positions"] = self._get_scan_positions( + affine_preprocessed, init_static_args["datacube"] + ) - ptycho_preprocessed = cls.__init__(**init_args).preprocess(**preprocess_static_args) + ptycho_preprocessed = cls.__init__(**init_args).preprocess( + **preprocess_static_args + ) def obj(**kwargs): return ptycho_preprocessed - def prep(ptycho,**kwargs): + + def prep(ptycho, **kwargs): return ptycho else: From cf849140e9d078ef9a45da1bbc99fbb2b73b53d5 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 15:04:18 -0400 Subject: [PATCH 072/362] preprocess caching bug fixed --- py4DSTEM/process/phase/parameter_optimize.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 292df27b6..2e52a677a 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -311,7 +311,7 @@ def _get_optimization_function( affine_preprocessed, init_static_args["datacube"] ) - ptycho_preprocessed = cls.__init__(**init_args).preprocess( + ptycho_preprocessed = cls(**init_args).preprocess( **preprocess_static_args ) @@ -323,9 +323,9 @@ def prep(ptycho, **kwargs): else: obj = partial(cls, **init_static_args) - affine = partial(AffineTransform, **affine_static_args) prep = partial(cls.preprocess, **preprocess_static_args) + affine = partial(AffineTransform, **affine_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) # Target function for Gaussian process optimization that takes a single @@ -364,6 +364,7 @@ def _set_optimizer_defaults(self): self._reconstruction_static_args["progress_bar"] = False self._reconstruction_static_args["store_iterations"] = False + self._reconstruction_static_args["reset"] = True class OptimizationParameter: From d7a1537bd56aa63dace33b39de6c10df670bb633 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sun, 25 Jun 2023 13:05:14 -0400 Subject: [PATCH 073/362] use log error for optimizer --- py4DSTEM/process/phase/parameter_optimize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 2e52a677a..3676616a4 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -348,7 +348,7 @@ def f(**kwargs): prep(ptycho, **prep_args) recon(ptycho, **reco_args) - return ptycho.error + return np.log(ptycho.error) return f From f04fc10d4bf31f5014bc7bde5dae40f80f11ebed Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 26 Jun 2023 19:55:04 -0700 Subject: [PATCH 074/362] fix for ws2 notebook --- py4DSTEM/process/diffraction/crystal_ACOM.py | 9 +++++---- py4DSTEM/process/utils/elliptical_coords.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index b303ee916..5c69a8ae2 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -776,7 +776,7 @@ def match_orientations( ): orientation = self.match_single_pattern( - bragg_peaks_array.get_pointlist(rx, ry), + bragg_peaks_array.cal[rx, ry], num_matches_return=num_matches_return, min_number_peaks=min_number_peaks, inversion_symmetry=inversion_symmetry, @@ -1616,9 +1616,10 @@ def calculate_strain( # Initialize empty strain maps strain_map = RealSlice( data=np.zeros(( + 5, bragg_peaks_array.shape[0], - bragg_peaks_array.shape[1], - 5)), + bragg_peaks_array.shape[1] + )), slicelabels=('e_xx','e_yy','e_xy','theta','mask'), name='strain_map') if mask_from_corr: @@ -1646,7 +1647,7 @@ def calculate_strain( disable=not progress_bar, ): # Get bragg peaks from experiment and reference - p = bragg_peaks_array.get_pointlist(rx,ry) + p = bragg_peaks_array.cal[rx,ry] if p.data.shape[0] >= min_num_peaks: p_ref = self.generate_diffraction_pattern( diff --git a/py4DSTEM/process/utils/elliptical_coords.py b/py4DSTEM/process/utils/elliptical_coords.py index 8bc80db79..97291bc20 100644 --- a/py4DSTEM/process/utils/elliptical_coords.py +++ b/py4DSTEM/process/utils/elliptical_coords.py @@ -151,7 +151,7 @@ def cartesian_to_polarelliptical_transform( * **pp**: *(2D array)* meshgrid of the phi coordinates """ if mask is None: - mask = np.ones_like(cartesianData, dtype=bool) + mask = np.ones_like(cartesianData.data, dtype=bool) assert ( cartesianData.shape == mask.shape ), "Mask and cartesian data array shapes must match." From f9598d180d7d09d53d525eae8537276e4f076f38 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 27 Jun 2023 18:00:51 -0400 Subject: [PATCH 075/362] bugfixes --- py4DSTEM/data/calibration.py | 613 ++++++++++++++---- py4DSTEM/data/data.py | 89 ++- py4DSTEM/data/datacube.py | 221 ++++--- py4DSTEM/data/propagating_calibration.py | 69 +- py4DSTEM/io/__init__.py | 3 +- py4DSTEM/io/google_drive_downloader.py | 145 ++++- py4DSTEM/io/read.py | 27 + py4DSTEM/io/sample_file_ids.py | 93 --- py4DSTEM/visualize/show.py | 2 +- test/gettestdata.py | 4 +- test/test_braggvectors.py | 2 +- test/test_calibration.py | 2 +- test/test_native_io/test_calibration_io.py | 64 +- test/test_native_io/test_realslice_read.py | 2 +- test/test_native_io/test_single_object_io.py | 362 +++++------ test/test_native_io/test_v0_13.py | 2 +- test/test_native_io/test_v0_14.py | 4 +- test/test_native_io/test_v0_9.py | 2 +- test/test_nonnative_io/test_dm.py | 2 +- test/test_workflow/test_basics.py | 2 +- .../test_disk_detection_basic.py | 2 +- .../test_disk_detection_with_calibration.py | 2 +- 22 files changed, 1120 insertions(+), 594 deletions(-) diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index e96d61e8b..a9937612d 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -3,45 +3,185 @@ import numpy as np from numbers import Number from typing import Optional +from warnings import warn -from emdfile import Metadata -from py4DSTEM.data.propagating_calibration import propagating_calibration +from emdfile import Metadata,Root +from py4DSTEM.data.propagating_calibration import call_calibrate class Calibration(Metadata): """ Stores calibration measurements. - Usage: + Usage + ----- + For some calibration instance `c` + + >>> c['x'] = y + + will set the value of some calibration item called 'x' to y, and + + >>> _y = c['x'] + + will return the value currently stored as 'x' and assign it to _y. + Additionally, for calibration items in the list `l` given below, + the syntax - >>> c = Calibration() >>> c.set_p(p) >>> p = c.get_p() - If the parameter has not been set, the getter methods return None. For - parameters with multiple values, they're returned as a tuple. If any of - the multiple values can't be found, a single None is returned instead. - Some parameters may have distinct values for each scan position; these - are stored as 2D arrays, and + is equivalent to + + >>> c.p = p + >>> p = c.p + + is equivalent to + + >>> c['p'] = p + >>> p = c['p'] + + where in the first line of each couplet the parameter `p` is set and in + the second it's retrieved, for parameters p in the list + + calibrate + --------- + l = [ + Q_pixel_size, * + R_pixel_size, * + Q_pixel_units, * + R_pixel_units, * + qx0, + qy0, + qx0_mean, + qy0_mean, + qx0shift, + qy0shift, + origin, * + origin_meas, + origin_meas_mask, + origin_shift, + a, * + b, * + theta, * + p_ellipse, * + ellipse, * + QR_rotation_degrees, + QR_flip, + QR_rotflip, * + probe_semiangle, + probe_param, + probe_center, + probe_convergence_semiangle_pixels, + probe_convergence_semiangle_mrad, + ] + + There are two advantages to using the getter/setter syntax for parameters + in `l` (e.g. either c.set_p or c.p) instead of the normal dictionary-like + getter/setter syntax (i.e. c['p']). These are (1) enabling retrieving + parameters by beam scan position, and (2) enabling propagation of any + calibration changes to downstream data objects which are affected by the + altered calibrations. See below. + + Get a parameter by beam scan position + ------------------------------------- + Some parameters support retrieval by beam scan position. In these cases, + calling - >>> c.get_p() + >>> c.get_p(rx,ry) - will return the entire 2D array, while + will return the value of parameter p at beam position (rx,ry). This works + only for the above syntax. Using either of - >>> c.get_p(rx,ry) + >>> c.p + >>> c['p'] + + will return an R-space shaped array. + + Trigger downstream calibrations + ------------------------------- + Some objects store their own internal calibration state, which depends on + the calibrations stored here. For example, a DataCube stores dimension + vectors which calibrate its 4 dimensions, and which depend on the pixel + sizes and the origin position. + + Modifying certain parameters therefore can trigger other objects which + depend on these parameters to re-calibrate themselves by calling their + .calibrate() method, if the object has one. Methods marked with a * in the + list `l` above have this property. Only objects registered with the + Calibration instance will have their .calibrate method triggered by changing + these parameters. An object `data` can be registered by calling + + >>> c.register_target( data ) + + and deregistered with + + >>> c.deregister_target( data ) + + If an object without a .calibrate method is registerd when a * method is + called, nothing happens. + + The .calibrate methods are triggered by setting some parameter `p` using + either + + >>> c.set_p( val ) + + or + + >>> c.p = val + + syntax. Setting the parameter with + + >>> c['p'] = val + + will not trigger re-calibrations. + + Calibration + Data + ------------------ + Data in py4DSTEM is stored in filetree like representations, and + Calibration instances are the top-level objects in these trees, + in that they live here: + + Root + |--metadata + | |-- *****---> calibration <---***** + | + |--some_object(e.g.datacube) + | |--another_object(e.g.max_dp) + | |--etc. + |--etc. + : - will return the value of `p` at position `rx,ry`. + Every py4DSTEM Data object has a tree with a calibration, and calling - The Calibration object is capable of automatically calling the ``calibrate`` method - of any other py4DSTEM objects when certain calibrations are updated. The methods - that trigger propagation of calibration information are tagged with the - @propagating_calibration decorator. Use the ``register_target`` method - to set up an object to recieve calls to ``calibrate`` + >>> data.calibration + will return the that Calibration instance. See also the docstring + for the `Data` class. + + Attaching an object to a different Calibration + ---------------------------------------------- + To modify the calibration associated with an object's `data`, use + + >>> c.attach( data ) + + where `c` is the new calibration instance `data` is to be associated + with. This (1) moves `data` into the top level of `c`'s data tree, + which means the new calibration will now be accessible normally at + + >>> data.calibration + + and (2) if and only if `data` was registered with its old calibration, + de-registers it there and registers it with the new calibration. If + `data` was not registered with the old calibration and it should be + registered with the new one, `c.register_target( data )` should be + called. + + To attach `data` to a different location in the calibration instance's + tree, use `data.attach( node )`. See the Data.attach docstring. """ def __init__( self, name: Optional[str] = 'calibration', - datacube = None + root: Optional[Root] = None, ): """ Args: @@ -49,15 +189,18 @@ def __init__( """ Metadata.__init__( self, - name=name) + name=name + ) + + # Set the root + if root is None: + root = Root( name="py4DSTEM_root" ) + self.set_root(root) # List to hold objects that will re-`calibrate` when # certain properties are changed self._targets = [] - # set datacube - self._datacube = datacube - # set initial pixel values self.set_Q_pixel_size(1) self.set_R_pixel_size(1) @@ -65,97 +208,141 @@ def __init__( self.set_R_pixel_units('pixels') - - # datacube - + # EMD root property @property - def datacube(self): - return self._datacube + def root(self): + return _root + @root.setter + def root(self): + raise Exception("Calibration.root does not support assignment; to change the root, use self.set_root") + def set_root(self,root): + assert(isinstance(root,Root)), f"root must be a Root, not type {type(root)}" + self._root = root + + + # Attach data to the calibration instance + def attach(self,data): + """ + Attach `data` to this calibration instance, placing it in the top + level of the Calibration instance's tree. If `data` was in a + different data tree, remove it. If `data` was registered with + a different calibration instance, de-register it there and + register it here. If `data` was not previously registerd and it + should be, after attaching it run `self.register_target(data)`. + """ + from py4DSTEM.data import Data + assert(isinstance(data,Data)), f"data must be a Data instance" + data.attach(self.root) + # Register for auto-calibration + def register_target(self,new_target): + """ + Register an object to recieve calls to it `calibrate` + method when certain calibrations get updated + """ + if new_target not in self._targets: + self._targets.append(new_target) + def unregister_target(self,target): + """ + Unlink an object from recieving calls to `calibrate` when + certain calibration values are changed + """ + if target in self._targets: + self._targets.remove(target) + + @property + def targets(self): + return tuple(self._targets) - ### getter/setter methods + ######### Begin Calibration Metadata Params ######### # pixel size/units - @propagating_calibration + @call_calibrate def set_Q_pixel_size(self,x): - if self._has_datacube(): - self.datacube.set_dim(2,x) - self.datacube.set_dim(3,x) self._params['Q_pixel_size'] = x def get_Q_pixel_size(self): return self._get_value('Q_pixel_size') + # aliases + @property + def Q_pixel_size(self): + return self.get_Q_pixel_size() + @Q_pixel_size.setter + def Q_pixel_size(self,x): + self.set_Q_pixel_size(x) + @property + def qpixsize(self): + return self.get_Q_pixel_size() + @qpixsize.setter + def qpixsize(self,x): + self.set_Q_pixel_size(x) - @propagating_calibration + @call_calibrate def set_R_pixel_size(self,x): - if self._has_datacube(): - self.datacube.set_dim(0,x) - self.datacube.set_dim(1,x) self._params['R_pixel_size'] = x def get_R_pixel_size(self): return self._get_value('R_pixel_size') + # aliases + @property + def R_pixel_size(self): + return self.get_R_pixel_size() + @R_pixel_size.setter + def R_pixel_size(self,x): + self.set_R_pixel_size(x) + @property + def qpixsize(self): + return self.get_R_pixel_size() + @qpixsize.setter + def qpixsize(self,x): + self.set_R_pixel_size(x) - @propagating_calibration + @call_calibrate def set_Q_pixel_units(self,x): assert(x in ('pixels','A^-1','mrad')), f"Q pixel units must be 'A^-1', 'mrad' or 'pixels'." - if self._has_datacube(): - self.datacube.set_dim_units(2,x) - self.datacube.set_dim_units(3,x) self._params['Q_pixel_units'] = x def get_Q_pixel_units(self): return self._get_value('Q_pixel_units') + # aliases + @property + def Q_pixel_units(self): + return self.get_Q_pixel_units() + @Q_pixel_units.setter + def Q_pixel_units(self,x): + self.set_Q_pixel_units(x) + @property + def qpixunits(self): + return self.get_Q_pixel_units() + @qpixunits.setter + def qpixunits(self,x): + self.set_Q_pixel_units(x) - @propagating_calibration + @call_calibrate def set_R_pixel_units(self,x): - if self._has_datacube(): - self.datacube.set_dim_units(0,x) - self.datacube.set_dim_units(1,x) self._params['R_pixel_units'] = x def get_R_pixel_units(self): return self._get_value('R_pixel_units') - - - - # datacube shape - - def get_R_Nx(self): - self._validate_datacube() - return self.datacube.R_Nx - def get_R_Ny(self): - self._validate_datacube() - return self.datacube.R_Ny - def get_Q_Nx(self): - self._validate_datacube() - return self.datacube.Q_Nx - def get_Q_Ny(self): - self._validate_datacube() - return self.datacube.Q_Ny - def get_datacube_shape(self): - self._validate_datacube() - """ (R_Nx,R_Ny,Q_Nx,Q_Ny) - """ - return self.datacube.data.dshape - def get_Qshape(self,x): - self._validate_datacube() - return self.data.Qshape - def get_Rshape(self,x): - self._validate_datacube() - return self.data.Rshape - - # is there a datacube? - def _validate_datacube(self): - assert(self.datacube is not None), "Can't find shape attr because Calibration doesn't point to a DataCube" - def _has_datacube(self): - return(self.datacube is not None) - - + # aliases + @property + def R_pixel_units(self): + return self.get_R_pixel_units() + @R_pixel_units.setter + def R_pixel_units(self,x): + self.set_R_pixel_units(x) + @property + def rpixunits(self): + return self.get_R_pixel_units() + @rpixunits.setter + def rpixunits(self,x): + self.set_R_pixel_units(x) # origin + + # qx0,qy0 def set_qx0(self,x): self._params['qx0'] = x x = np.asarray(x) @@ -203,7 +390,60 @@ def set_origin_meas_mask(self,x): def get_origin_meas_mask(self,rx=None,ry=None): return self._get_value('origin_meas_mask',rx,ry) - @propagating_calibration + # aliases + @property + def qx0(self): + return self.get_qx0() + @qx0.setter + def qx0(self,x): + self.set_qx0(x) + @property + def qx0_mean(self): + return self.get_qx0_mean() + @qx0_mean.setter + def qx0_mean(self,x): + self.set_qx0_mean(x) + @property + def qx0shift(self): + return self.get_qx0shift() + @property + def qy0(self): + return self.get_qy0() + @qy0.setter + def qy0(self,x): + self.set_qy0(x) + @property + def qy0_mean(self): + return self.get_qy0_mean() + @qy0_mean.setter + def qy0_mean(self,x): + self.set_qy0_mean(x) + @property + def qy0_shift(self): + return self.get_qy0_shift() + @property + def qx0_meas(self): + return self.get_qx0_meas() + @qx0_meas.setter + def qx0_meas(self,x): + self.set_qx0_meas(x) + @property + def qy0_meas(self): + return self.get_qy0_meas() + @qy0_meas.setter + def qy0_meas(self,x): + self.set_qy0_meas(x) + @property + def origin_meas_mask(self): + return self.get_origin_meas_mask() + @origin_meas_mask.setter + def origin_meas_mask(self,x): + self.set_origin_meas_mask(x) + + + # origin = (qx0,qy0) + + @call_calibrate def set_origin(self,x): """ Args: @@ -252,44 +492,43 @@ def get_origin_meas(self,rx=None,ry=None): ans = None return ans - def set_probe_semiangle(self,x): - self._params['probe_semiangle'] = x - def get_probe_semiangle(self): - return self._get_value('probe_semiangle') - def set_probe_param(self, x): - """ - Args: - x (3-tuple): (probe size, x0, y0) - """ - probe_semiangle, qx0, qy0 = x - self.set_probe_semiangle(probe_semiangle) - self.set_qx0_mean(qx0) - self.set_qy0_mean(qy0) - def get_probe_param(self): - probe_semiangle = self._get_value('probe_semiangle') - qx0 = self._get_value('qx0') - qy0 = self._get_value('qy0') - ans = (probe_semiangle,qx0,qy0) - if any([x is None for x in ans]): - ans = None - return ans + # aliases + @property + def origin(self): + return self.get_origin() + @origin.setter + def origin(self,x): + self.set_origin(x) + @property + def origin_meas(self): + return self.get_origin_meas() + @origin_meas.setter + def origin_meas(self,x): + self.set_origin_meas(x) + @property + def origin_shift(self): + return self.get_origin_shift() # ellipse + + @call_calibrate def set_a(self,x): self._params['a'] = x def get_a(self,rx=None,ry=None): return self._get_value('a',rx,ry) + @call_calibrate def set_b(self,x): self._params['b'] = x def get_b(self,rx=None,ry=None): return self._get_value('b',rx,ry) + @call_calibrate def set_theta(self,x): self._params['theta'] = x def get_theta(self,rx=None,ry=None): return self._get_value('theta',rx,ry) - @propagating_calibration + @call_calibrate def set_ellipse(self,x): """ Args: @@ -300,7 +539,7 @@ def set_ellipse(self,x): self._params['b'] = b self._params['theta'] = theta - @propagating_calibration + @call_calibrate def set_p_ellipse(self,x): """ Args: @@ -323,7 +562,42 @@ def get_p_ellipse(self,rx=None,ry=None): a,b,theta = self.get_ellipse(rx,ry) return (qx0,qy0,a,b,theta) + # aliases + @property + def a(self): + return self.get_a() + @a.setter + def a(self,x): + self.set_a(x) + @property + def b(self): + return self.get_b() + @b.setter + def b(self,x): + self.set_b(x) + @property + def theta(self): + return self.get_theta() + @theta.setter + def theta(self,x): + self.set_theta(x) + @property + def p_ellipse(self): + return self.get_p_ellipse() + @p_ellipse.setter + def p_ellipse(self,x): + self.set_p_ellipse(x) + @property + def ellipse(self): + return self.get_ellipse() + @ellipse.setter + def ellipse(self,x): + self.set_ellipse(x) + + + # Q/R-space rotation and flip + def set_QR_rotation_degrees(self,x): self._params['QR_rotation_degrees'] = x def get_QR_rotation_degrees(self): @@ -334,7 +608,7 @@ def set_QR_flip(self,x): def get_QR_flip(self): return self._get_value('QR_flip') - @propagating_calibration + @call_calibrate def set_QR_rotflip(self, rot_flip): """ Args: @@ -352,21 +626,113 @@ def get_QR_rotflip(self): return None return (rot,flip) + # aliases + @property + def QR_rotation_degrees(self): + return self.get_QR_rotation_degrees() + @QR_rotation_degrees.setter + def QR_rotation_degrees(self,x): + self.set_QR_rotation_degrees(x) + @property + def QR_flip(self): + return self.get_QR_flip() + @QR_flip.setter + def QR_flip(self,x): + self.set_QR_flip(x) + @property + def QR_rotflip(self): + return self.get_QR_rotflip() + @QR_rotflip.setter + def QR_rotflip(self,x): + self.set_QR_rotflip(x) + + + + # probe + + def set_probe_semiangle(self,x): + self._params['probe_semiangle'] = x + def get_probe_semiangle(self): + return self._get_value('probe_semiangle') + def set_probe_param(self, x): + """ + Args: + x (3-tuple): (probe size, x0, y0) + """ + probe_semiangle, qx0, qy0 = x + self.set_probe_semiangle(probe_semiangle) + self.set_qx0_mean(qx0) + self.set_qy0_mean(qy0) + def get_probe_param(self): + probe_semiangle = self._get_value('probe_semiangle') + qx0 = self._get_value('qx0') + qy0 = self._get_value('qy0') + ans = (probe_semiangle,qx0,qy0) + if any([x is None for x in ans]): + ans = None + return ans + def set_convergence_semiangle_pixels(self,x): self._params['convergence_semiangle_pixels'] = x def get_convergence_semiangle_pixels(self): return self._get_value('convergence_semiangle_pixels') - def set_convergence_semiangle_pixels(self,x): + def set_convergence_semiangle_mrad(self,x): self._params['convergence_semiangle_mrad'] = x - def get_convergence_semiangle_pixels(self): + def get_convergence_semiangle_mrad(self): return self._get_value('convergence_semiangle_mrad') def set_probe_center(self,x): self._params['probe_center'] = x def get_probe_center(self): return self._get_value('probe_center') + #aliases + @property + def probe_semiangle(self): + return self.get_probe_semiangle() + @probe_semiangle.setter + def probe_semiangle(self,x): + self.set_probe_semiangle(x) + @property + def probe_param(self): + return self.get_probe_param() + @probe_param.setter + def probe_param(self,x): + self.set_probe_param(x) + @property + def probe_center(self): + return self.get_probe_center() + @probe_center.setter + def probe_center(self,x): + self.set_probe_center(x) + @property + def probe_convergence_semiangle_pixels(self): + return self.get_probe_convergence_semiangle_pixels() + @probe_convergence_semiangle_pixels.setter + def probe_convergence_semiangle_pixels(self,x): + self.set_probe_convergence_semiangle_pixels(x) + @property + def probe_convergence_semiangle_mrad(self): + return self.get_probe_convergence_semiangle_mrad() + @probe_convergence_semiangle_mrad.setter + def probe_convergence_semiangle_mrad(self,x): + self.set_probe_convergence_semiangle_mrad(x) + + + + + + ######## End Calibration Metadata Params ######## + + + + # calibrate targets + @call_calibrate + def calibrate(self): + pass + + # For parameters which can have 2D or (2+n)D array values, # this function enables returning the value(s) at a 2D position, @@ -399,31 +765,24 @@ def copy(self,name=None): return cal - # Methods for assigning objects which will be - # auto-calibrated when the Calibration instance is updated - - def register_target(self,new_target): - """ - Register an object to recieve calls to it `calibrate` - method when certain calibrations get updated - """ - self._targets.append(new_target) - - def unregister_target(self,target): - """ - Unlink an object from recieving calls to `calibrate` when - certain calibration values are changed - """ - if target in self._targets: - self._targets.remove(target) - # HDF5 i/o # write is inherited from Metadata + def to_h5(self,group): + """ + Saves the metadata dictionary _params to group, then adds the + calibration's target's list + """ + # Add targets list to metadata + targets = [x._treepath for x in self.targets] + self['_target_paths'] = targets + # Save the metadata + Metadata.to_h5(self,group) # read - def from_h5(group): + @classmethod + def from_h5(cls,group): """ Takes a valid group for an HDF5 file object which is open in read mode. Determines if it's a valid Metadata representation, and diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index 0f6d10d52..c2c4aef50 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -1,5 +1,5 @@ # Base class for all py4DSTEM data -# which adds a pointer to 'calibration' metadata +# which adds an EMD root and a pointer to 'calibration' metadata import warnings @@ -8,26 +8,80 @@ class Data: + """ + Data in py4DSTEM is stored in filetree like representations, e.g. + + Root + |--metadata + | |--calibration + | + |--some_object(e.g.datacube) + | |--another_object(e.g.max_dp) + | |--etc. + | + |--one_more_object(e.g.crystal) + | |--etc. + : + + In a Python interpreter, do + + >>> data.tree(True) + + to display the data tree of Data instance `data`, and + + >>> data.tree() + + to display the tree of from the current node on, i.e. the branch + downstream of `data`. + + Every object can access the calibrations which live in the root metadata + of its tree with + + >>> data.calibration + + which returns the calibrations, or, if none are found, raises a warning + and returns None. + + Some objects should be modified when the calibrations change - these + objects must have .calibrate() method, which is called any time relevant + calibration parameters change if the object has been registered with + the calibrations. + + To transfer `data` from it's current tree to another existing tree, use + + >>> data.attach(some_other_data) + + which will move the data to the new tree. If the data was registered with + it's old calibrations, this will also de-register it there and register + it with the new calibrations such that .calibrate() is called when it + should be. + + See also the Calibration docstring. + """ def __init__( self, - setup_tree = True, calibration = None ): - assert(isinstance(self,Node)), "Data instances must alse inherit from Node" + assert(isinstance(self,Node)), "Data instances must inherit from Node" pass - if setup_tree: - # set up EMD tree + # set up calibration + EMD tree + if calibration is None: root = Root( name = self.name+"_root" ) root.tree( self ) - - # set up calibration - calibration = Calibration() if calibration is None else calibration - self._setup_calibration( calibration ) + self.calibration = Calibration() + else: + assert(isinstance(calibration,Calibration)), f"`calibration` must be a Calibration, not type {type(calibration)}" + self.calibration = calibration + if calibration.root is None: + calibration._root = Root( name = self.name+"_root" ) + calibration.root.tree( self ) + else: + calibration.root.tree( self ) - # calibration + # calibration property @property def calibration(self): @@ -49,6 +103,21 @@ def calibration(self, x): self.root.metadata['calibration'] = x + # transfer trees + + def attach(self,node): + """ + Moves self to `node`'s tree, attaching to node's calibration and detaching + from the current calibration. + """ + assert(isinstance(node,Node)), f"node must be a Node, not type {type(node)}" + assert(hasattr(node,'calibration')), "node must have a calibration" + if self in self.calibration._targets: + register = True + self.calibration.unregister_target(self) + node.graft(self) + if register: + self.calibration.register_target(self) diff --git a/py4DSTEM/data/datacube.py b/py4DSTEM/data/datacube.py index c573b7e30..775ca75a8 100644 --- a/py4DSTEM/data/datacube.py +++ b/py4DSTEM/data/datacube.py @@ -10,7 +10,6 @@ - class DataCube(Array,Data): """ Storage and processing methods for 4D-STEM datasets. @@ -21,7 +20,6 @@ def __init__( data: np.ndarray, name: Optional[str] = 'datacube', slicelabels: Optional[Union[bool,list]] = None, - setup_tree: Optional[bool] = True, calibration: Optional[Union[Calibration,None]] = None, ): """ @@ -31,7 +29,6 @@ def __init__( calibration (None or Calibration or 'pass'): default (None) creates and attaches a new Calibration instance to root metadata, or, passing a Calibration instance uses this instead. - 'skip' is for internal use for the reader slicelabels (None or list): names for slices if this is a stack of datacubes @@ -56,114 +53,103 @@ def __init__( # initialize as Data Data.__init__( self, - setup_tree, calibration ) + # register with calibration + self.calibration.register_target(self) + # cartesian coords - # TODO - tmp hack, needs to be refactored - - # this will break when preprocess methods are called - self.qyy,self.qxx = np.meshgrid( - np.arange(0,self.Q_Ny), - np.arange(0,self.Q_Nx) - ) + self.calibrate() # polar coords self.polar = None - def _setup_calibration(self, cal): - """ - Ensures that a calibration instance exists. Passing None - makes a new Calibration instance, puts it in root.calibration, and - makes a two way link. Passing a Calibration instance attaches that - instance. `'skip'` does nothing (internal use, on read from file). - """ - if cal is None: - self.calibration = Calibration( datacube = self ) - elif cal == 'skip': - pass - else: - assert(isinstance(cal, Calibration)), "`calibration` must be a Calibration instance, not type f{type(cal)}" - self.calibration = cal - cal._datacube = self - - def copy(self): + def calibrate(self): """ - Copys datacube + Calibrate the coordinate axes of the datacube. Using the calibrations + at self.calibration, sets the 4 dim vectors (Qx,Qy,Rx,Ry) according + to the pixel size, units and origin positions, then updates the + meshgrids representing Q and R space. """ - from py4DSTEM import DataCube - new_datacube = DataCube( - data = self.data.copy(), - name = self.name, - calibration = self.calibration.copy(), - slicelabels = self.slicelabels, - ) + assert(self.calibration is not None), "No calibration found!" - Qpixsize = new_datacube.calibration.get_Q_pixel_size() - Qpixunits = new_datacube.calibration.get_Q_pixel_units() - Rpixsize = new_datacube.calibration.get_R_pixel_size() - Rpixunits = new_datacube.calibration.get_R_pixel_units() + # Get calibration values + rpixsize = self.calibration.get_R_pixel_size() + rpixunits = self.calibration.get_R_pixel_units() + qpixsize = self.calibration.get_Q_pixel_size() + qpixunits = self.calibration.get_Q_pixel_units() + origin = self.calibration.get_origin_mean() + if origin is None or origin==(None,None): + origin = (0,0) - new_datacube.set_dim( + # Calc dim vectors + dim_rx = np.arange(self.R_Nx)*rpixsize + dim_ry = np.arange(self.R_Ny)*rpixsize + dim_qx = -origin[0] + np.arange(self.Q_Nx)*qpixsize + dim_qy = -origin[1] + np.arange(self.Q_Ny)*qpixsize + + # Set dim vectors + self.set_dim( 0, - [0,Rpixsize], - units = Rpixunits, - name = 'Rx' + dim_rx, + units = rpixunits ) - new_datacube.set_dim( + self.set_dim( 1, - [0,Rpixsize], - units = Rpixunits, - name = 'Ry' + dim_ry, + units = rpixunits ) - - new_datacube.set_dim( + self.set_dim( 2, - [0,Qpixsize], - units = Qpixunits, - name = 'Qx' + dim_qx, + units = qpixunits ) - new_datacube.set_dim( + self.set_dim( 3, - [0,Qpixsize], - units = Qpixunits, - name = 'Qy' + dim_qy, + units = qpixunits ) - return new_datacube + # Set meshgrids + self._qxx,self._qyy = np.meshgrid( dim_qx,dim_qy ) + self._rxx,self._ryy = np.meshgrid( dim_rx,dim_ry ) - # properties - - ## pixel size / units - - # Q + # coordinate meshgrids @property - def Q_pixel_size(self): - return self.calibration.get_Q_pixel_size() + def rxx(self): + return self._rxx @property - def Q_pixel_units(self): - return self.calibration.get_Q_pixel_units() - - # R + def ryy(self): + return self._ryy @property - def R_pixel_size(self): - return self.calibration.get_R_pixel_size() + def qxx(self): + return self._qxx @property - def R_pixel_units(self): - return self.calibration.get_R_pixel_units() + def qyy(self): + return self._qyy + + # coordinate meshgrids with shifted origin + def qxxs(self,rx,ry): + qx0_shift = self.calibration.get_qx0shift(rx,ry) + if qx0_shift is None: + raise Exception("Can't compute shifted meshgrid - origin shift is not defined") + return qxx - qx0_shift + def qyys(self,rx,ry): + qy0_shift = self.calibration.get_qy0shift(rx,ry) + if qy0_shift is None: + raise Exception("Can't compute shifted meshgrid - origin shift is not defined") + return qyy - qy0_shift - # aliases - qpixsize = Q_pixel_size - qpixunit = Q_pixel_units - rpixsize = R_pixel_size - rpixunit = R_pixel_units + # shape properties + ## shape # FOV @@ -202,6 +188,85 @@ def R_N(self): + ## pixel size / units + + # Q + @property + def Q_pixel_size(self): + return self.calibration.get_Q_pixel_size() + @property + def Q_pixel_units(self): + return self.calibration.get_Q_pixel_units() + + # R + @property + def R_pixel_size(self): + return self.calibration.get_R_pixel_size() + @property + def R_pixel_units(self): + return self.calibration.get_R_pixel_units() + + # aliases + qpixsize = Q_pixel_size + qpixunit = Q_pixel_units + rpixsize = R_pixel_size + rpixunit = R_pixel_units + + + + + + + def copy(self): + """ + Copys datacube + """ + from py4DSTEM import DataCube + new_datacube = DataCube( + data = self.data.copy(), + name = self.name, + calibration = self.calibration.copy(), + slicelabels = self.slicelabels, + ) + + Qpixsize = new_datacube.calibration.get_Q_pixel_size() + Qpixunits = new_datacube.calibration.get_Q_pixel_units() + Rpixsize = new_datacube.calibration.get_R_pixel_size() + Rpixunits = new_datacube.calibration.get_R_pixel_units() + + new_datacube.set_dim( + 0, + [0,Rpixsize], + units = Rpixunits, + name = 'Rx' + ) + new_datacube.set_dim( + 1, + [0,Rpixsize], + units = Rpixunits, + name = 'Ry' + ) + + new_datacube.set_dim( + 2, + [0,Qpixsize], + units = Qpixunits, + name = 'Qx' + ) + new_datacube.set_dim( + 3, + [0,Qpixsize], + units = Qpixunits, + name = 'Qy' + ) + + return new_datacube + + + + + + # I/O @@ -223,7 +288,7 @@ def _get_constructor_args(cls,group): 'data': ar_args['data'], 'name': ar_args['name'], 'slicelabels': ar_args['slicelabels'], - 'calibration': 'skip' + 'calibration': None } return args diff --git a/py4DSTEM/data/propagating_calibration.py b/py4DSTEM/data/propagating_calibration.py index 8b1196ee6..fa34f1468 100644 --- a/py4DSTEM/data/propagating_calibration.py +++ b/py4DSTEM/data/propagating_calibration.py @@ -1,13 +1,17 @@ +# Define decorators call_* which, when used to decorate class methods, +# calls all objects in a list _targets? to call some method *. + import warnings -class propagating_calibration(object): + +# This is the abstract pattern: + +class call_method(object): """ - A decorator which, when attached to a method of Calibration, - causes `calibrate` to be called on any objects in the - Calibration object's `_targets` list, following execution of + A decorator which, when attached to a method of SomeClass, + causes `method` to be called on any objects in the + instance's `_targets` list, following execution of the decorated function. - This allows objects associated with the Calibration to - automatically respond to changes in the calibration state. """ def __init__(self, func): self.func = func @@ -15,21 +19,22 @@ def __init__(self, func): def __call__(self, *args, **kwargs): """ Update the parameters the caller wanted by calling the wrapped - method, then loop through the list of targetsand call their + method, then loop through the list of targets and call their `calibrate` methods. """ self.func(*args,**kwargs) - - calibration = args[0] - assert hasattr(calibration, "_targets"), "Calibration object appears to be in an invalid state. _targets attribute is missing." - for target in calibration._targets: - if hasattr(target,'calibrate') and callable(target.calibrate): + some_object = args[0] + assert hasattr(some_object, "_targets"), "SomeObject object appears to be in an invalid state. _targets attribute is missing." + for target in some_object._targets: + if hasattr(target,'method') and callable(target,method): try: - target.calibrate() + target.method() except Exception as err: - print(f"Attempted to calibrate object {target} but this raised an error: {err}") + print(f"Attempted to call .method(), but this raised an error: {err}") else: - warnings.warn(f"{target} is registered as a target for calibration propagation but does not appear to have a calibrate() method") + # warn or pass or error out here, as needs be + #pass + warnings.warn(f"{target} is registered as a target but does not appear to have a .method() callable") def __get__(self, instance, owner): """ @@ -44,3 +49,37 @@ def __get__(self, instance, owner): from functools import partial return partial(self.__call__, instance) + +# This is a functional decorator, @call_calibrate: + +# calls: calibrate() +# targets: _targets + +class call_calibrate(object): + """ + Decorated methods cause all targets in _targets to call .calibrate(). + """ + def __init__(self, func): + self.func = func + + def __call__(self, *args, **kwargs): + """ + """ + self.func(*args,**kwargs) + calibration = args[0] + assert hasattr(calibration, "_targets"), "Calibration object appears to be in an invalid state. _targets attribute is missing." + for target in calibration._targets: + if hasattr(target,'calibrate') and callable(target.calibrate): + try: + target.calibrate() + except Exception as err: + print(f"Attempted to calibrate object {target} but this raised an error: {err}") + else: + pass + + def __get__(self, instance, owner): + """ + """ + from functools import partial + return partial(self.__call__, instance) + diff --git a/py4DSTEM/io/__init__.py b/py4DSTEM/io/__init__.py index 71a0f2dd5..80b591f8a 100644 --- a/py4DSTEM/io/__init__.py +++ b/py4DSTEM/io/__init__.py @@ -6,8 +6,7 @@ # google downloader -from py4DSTEM.io.google_drive_downloader import gdrive_download -from py4DSTEM.io.sample_file_ids import get_sample_file_ids +from py4DSTEM.io.google_drive_downloader import gdrive_download, get_sample_file_ids diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index a4ff72abe..c8b410d47 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -1,7 +1,127 @@ import gdown import os -from py4DSTEM.io.sample_file_ids import file_ids, collection_ids + +### File IDs + +# single files +file_ids = { + 'sample_diffraction_pattern' : ( + 'a_diffraction_pattern.h5', + '1ymYMnuDC0KV6dqduxe2O1qafgSd0jjnU', + ), + 'Au_sim' : ( + 'Au_sim.h5', + '1PmbCYosA1eYydWmmZebvf6uon9k_5g_S', + ), + 'carbon_nanotube' : ( + 'carbon_nanotube.h5', + '1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM', + ), + 'Si_SiGe_exp' : ( + 'Si_SiGe_exp.h5', + '1fXNYSGpe6w6E9RBA-Ai_owZwoj3w8PNC', + ), + 'Si_SiGe_probe' : ( + 'Si_SiGe_probe.h5', + '141Tv0YF7c5a-MCrh3CkY_w4FgWtBih80', + ), + 'Si_SiGe_EELS_strain' : ( + 'Si_SiGe_EELS_strain.h5', + '1klkecq8IuEOYB-bXchO7RqOcgCl4bmDJ', + ), + 'AuAgPd_wire' : ( + 'AuAgPd_wire.h5', + '1OQYW0H6VELsmnLTcwicP88vo2V5E3Oyt', + ), + 'AuAgPd_wire_probe' : ( + 'AuAgPd_wire_probe.h5', + '17OduUKpxVBDumSK_VHtnc2XKkaFVN8kq', + ), + 'polycrystal_2D_WS2' : ( + 'polycrystal_2D_WS2.h5', + '1AWB3-UTPiTR9dgrEkNFD7EJYsKnbEy0y', + ), + 'WS2cif' : ( + 'WS2.cif', + '13zBl6aFExtsz_sew-L0-_ALYJfcgHKjo', + ), + 'polymers' : ( + 'polymers.h5', + '1lK-TAMXN1MpWG0Q3_4vss_uEZgW2_Xh7', + ), + 'vac_probe' : ( + 'vac_probe.h5', + '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', + ), + 'small_dm3_3Dstack' : ( + 'small_dm3_3Dstack.dm3', + '1B-xX3F65JcWzAg0v7f1aVwnawPIfb5_o' + ), + 'FCU-Net' : ( + 'filename.name', + '1-KX0saEYfhZ9IJAOwabH38PCVtfXidJi', + ), + 'small_datacube' : ( + 'small_datacube.dm4', + # TODO - change this file to something smaller - ideally e.g. shape (4,8,256,256) ~= 4.2MB' + '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe' + ), + 'legacy_v0.9' : ( + 'legacy_v0.9_simAuNanoplatelet_bin.h5', + '1AIRwpcj87vK3ubLaKGj1UiYXZByD2lpu' + ), + 'legacy_v0.13' : ( + 'legacy_v0.13.h5', + '1VEqUy0Gthama7YAVkxwbjQwdciHpx8rA' + ), + 'legacy_v0.14' : ( + 'legacy_v0.14.h5', + '1eOTEJrpHnNv9_DPrWgZ4-NTN21UbH4aR', + ), + 'test_realslice_io' : ( + 'test_realslice_io.h5', + '1siH80-eRJwG5R6AnU4vkoqGWByrrEz1y' + ), +} + +# collections of files +collection_ids = { + 'tutorials' : ( + 'Au_sim', + 'carbon_nanotube', + 'Si_SiGe_exp', + 'Si_SiGe_probe', + 'Si_SiGe_EELS_strain', + 'AuAgPd_wire', + 'AuAgPd_wire_probe', + 'polycrystal_2D_WS2', + 'WS2cif', + 'polymers', + 'vac_probe', + ), + 'test_io' : ( + 'small_dm3_3Dstack', + 'vac_probe', + 'legacy_v0.9', + 'legacy_v0.13', + 'legacy_v0.14', + 'test_realslice_io', + ), + 'test_braggvectors' : ( + 'Au_sim', + ) +} + +def get_sample_file_ids(): + return { + 'files' : file_ids.keys(), + 'collections' : collection_ids.keys() + } + + + +### Downloader def gdrive_download( id_, @@ -19,22 +139,22 @@ def gdrive_download( File ID for the desired file. May be either a key from the list of files and collections of files accessible at get_sample_file_ids(), or a complete url, or the portions of a google drive link specifying - the file ID, i.e. for the address + it's google file ID, i.e. for the address https://drive.google.com/file/d/1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM/, the id string '1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM'. destination : None or str - The location to download to. If None, downloads to the current - working directory. If a string is passed which points to a valid - location on the filesystem, downloads there. For collections of - files, makes a new directory named after the collection id and - places all files there. + The location files are downloaded to. If a collection of files has been + specified, creates a new directory at the specified destination and + downloads the collection there. If None, downloads to the current + working directory. Otherwise must be a string or Path pointint to + a valid location on the filesystem. overwrite : bool Turns overwrite protection on/off. filename : None or str - Used only if `id_` is a url or gdrive id. Specifies the name of the - output file. If left as None, saves to 'gdrivedownload.file'. If `id_` - is a key from the sample file id list, this parameter is ignored and - the filenames in that list are used. + Used only if `id_` is a url or gdrive id. In these cases, specifies + the name of the output file. If left as None, saves to + 'gdrivedownload.file'. If `id_` is a key from the sample file id list, + this parameter is ignored. verbose : bool Toggles verbose output """ @@ -89,3 +209,6 @@ def gdrive_download( fuzzy = True ) + + + diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index e5d227b86..a28d06e16 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -3,6 +3,7 @@ from pathlib import Path from os.path import exists from typing import Optional,Union +import warnings import py4DSTEM import emdfile as emd @@ -81,11 +82,37 @@ def read( version = emd._get_EMD_version(filepath) if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" + # read data = emd.read( filepath, emdpath = datapath, tree = tree ) + # calibration links + if isinstance(data,py4DSTEM.Data): + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + cal = data.calibration + elif isinstance(data,py4DSTEM.Root): + try: + cal = data.metadata['calibration'] + except KeyError: + cal = None + else: + cal = None + if cal is not None: + try: + target_paths = cal['_target_paths'] + del(cal._params['_target_paths']) + for p in target_paths: + d = data.root.tree(p) + cal.register_target( d ) + if hasattr(d,'setcal'): + dsetcal() + except KeyError: + pass + cal.calibrate() + # return if verbose: print("Done.") return data diff --git a/py4DSTEM/io/sample_file_ids.py b/py4DSTEM/io/sample_file_ids.py index b53d63621..8b1378917 100644 --- a/py4DSTEM/io/sample_file_ids.py +++ b/py4DSTEM/io/sample_file_ids.py @@ -1,94 +1 @@ -# single files -file_ids = { - 'sample_diffraction_pattern' : ( - 'a_diffraction_pattern.h5', - '1ymYMnuDC0KV6dqduxe2O1qafgSd0jjnU', - ), - 'Au_sim' : ( - 'au_sim.h5', - '1PmbCYosA1eYydWmmZebvf6uon9k_5g_S', - ), - 'carbon_nanotube' : ( - 'carbon_nanotube.h5', - '1bHv3u61Cr-y_GkdWHrJGh1lw2VKmt3UM', - ), - 'Si_SiGe_exp' : ( - 'Si_SiGe_exp.h5', - '1fXNYSGpe6w6E9RBA-Ai_owZwoj3w8PNC', - ), - 'Si_SiGe_probe' : ( - 'Si_SiGe_probe.h5', - '141Tv0YF7c5a-MCrh3CkY_w4FgWtBih80', - ), - 'Si_SiGe_EELS_strain' : ( - 'Si_SiGe_EELS_strain.h5', - '1klkecq8IuEOYB-bXchO7RqOcgCl4bmDJ', - ), - 'AuAgPd_wire' : ( - 'AuAgPd_wire.h5', - '1OQYW0H6VELsmnLTcwicP88vo2V5E3Oyt', - ), - 'AuAgPd_wire_probe' : ( - 'AuAgPd_wire_probe.h5', - '17OduUKpxVBDumSK_VHtnc2XKkaFVN8kq', - ), - 'polycrystal_2D_WS2' : ( - 'polycrystal_2D_WS2.h5', - '1AWB3-UTPiTR9dgrEkNFD7EJYsKnbEy0y', - ), - 'WS2cif' : ( - 'WS2.cif', - '13zBl6aFExtsz_sew-L0-_ALYJfcgHKjo', - ), - 'polymers' : ( - 'polymers.h5', - '1lK-TAMXN1MpWG0Q3_4vss_uEZgW2_Xh7', - ), - 'vac_probe' : ( - 'vac_probe.h5', - '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe', - ), - 'small_dm3_3Dstack' : ( - 'small_dm3_3Dstack.dm3', - '1B-xX3F65JcWzAg0v7f1aVwnawPIfb5_o' - ), - 'FCU-Net' : ( - 'filename.name', - '1-KX0saEYfhZ9IJAOwabH38PCVtfXidJi', - ), - 'small_datacube' : ( - 'small_datacube.dm4', - # TODO - change this file to something smaller - ideally e.g. shape (4,8,256,256) ~= 4.2MB' - '1QTcSKzZjHZd1fDimSI_q9_WsAU25NIXe' - ), -} - -# collections of files -collection_ids = { - 'tutorials' : ( - 'Au_sim', - 'carbon_nanotube', - 'Si_SiGe_exp', - 'Si_SiGe_probe', - 'Si_SiGe_EELS_strain', - 'AuAgPd_wire', - 'AuAgPd_wire_probe', - 'polycrystal_2D_WS2', - 'WS2cif', - 'polymers', - 'vac_probe', - ), - 'io_test_data' : ( - 'small_dm3_3Dstack', - 'vac_probe', - ), -} - - -def get_sample_file_ids(): - return { - 'files' : file_ids.keys(), - 'collections' : collection_ids.keys() - } - diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 448a44590..20ed0be2b 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -553,7 +553,7 @@ def show( # Create colormap with mask_color for bad values - cm = copy(plt.cm.get_cmap(cmap)) + cm = copy(plt.colormaps.get_cmap(cmap)) if mask_color=='empty': cm.set_bad(alpha=0) else: diff --git a/test/gettestdata.py b/test/gettestdata.py index a370cdcc1..0b5608a7c 100644 --- a/test/gettestdata.py +++ b/test/gettestdata.py @@ -54,7 +54,7 @@ if args.data == 'tutorials': data = 'tutorials' elif args.data == 'io': - data = 'io_test_data' + data = 'test_io' elif args.data == 'basic': data = 'small_datacube' else: @@ -69,7 +69,7 @@ ) # Always download the basic datacube -if args.data is not 'basic': +if args.data != 'basic': download( 'small_datacube', destination = testpath, diff --git a/test/test_braggvectors.py b/test/test_braggvectors.py index 901317c05..e8a8d5ccc 100644 --- a/test/test_braggvectors.py +++ b/test/test_braggvectors.py @@ -3,7 +3,7 @@ from os.path import join # set filepath -path = join(py4DSTEM._TESTPATH,"simulatedAuNanoplatelet_binned_v0_9.h5") +path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") diff --git a/test/test_calibration.py b/test/test_calibration.py index eb600fa3a..80cb03493 100644 --- a/test/test_calibration.py +++ b/test/test_calibration.py @@ -6,7 +6,7 @@ # set filepaths path_datacube = join(py4DSTEM._TESTPATH, "small_datacube.dm4") -path_3Darray = join(py4DSTEM._TESTPATH, "io_test_data/small_dm3_3Dstack.dm3") +path_3Darray = join(py4DSTEM._TESTPATH, "test_io/small_dm3_3Dstack.dm3") path_out_dir = join(py4DSTEM._TESTPATH, "test_outputs") path_out = join(path_out_dir, "test_calibration.h5") diff --git a/test/test_native_io/test_calibration_io.py b/test/test_native_io/test_calibration_io.py index 7aaa42d30..a753c7c81 100644 --- a/test/test_native_io/test_calibration_io.py +++ b/test/test_native_io/test_calibration_io.py @@ -3,38 +3,38 @@ from os.path import join # set filepath -path = join(py4DSTEM._TESTPATH, "filename") - - - -class TestCalibrationIO: - - - - def test_datacube_cal_io(self): - # TODO - # make a datacube - # modify its calibration - # save - # load the datacube - # check its calibration - assert 0 - pass - - - def test_datacube_child_node(self): - # TODO - # make a datacube - # make a child node - # confirm calibrations are the same - # modify the calibration - # save - # load the datacube - # check its calibration - # load just the child node - # check its calibration - assert 0 - pass +#path = join(py4DSTEM._TESTPATH, "filename") + + + +# class TestCalibrationIO: +# +# +# +# def test_datacube_cal_io(self): +# # TODO +# # make a datacube +# # modify its calibration +# # save +# # load the datacube +# # check its calibration +# assert 0 +# pass +# +# +# def test_datacube_child_node(self): +# # TODO +# # make a datacube +# # make a child node +# # confirm calibrations are the same +# # modify the calibration +# # save +# # load the datacube +# # check its calibration +# # load just the child node +# # check its calibration +# assert 0 +# pass diff --git a/test/test_native_io/test_realslice_read.py b/test/test_native_io/test_realslice_read.py index a1a8f09e7..8fb577ad8 100644 --- a/test/test_native_io/test_realslice_read.py +++ b/test/test_native_io/test_realslice_read.py @@ -6,7 +6,7 @@ # Set filepaths -filepath = join(py4DSTEM._TESTPATH, "YanAiming_bilayer_v01.h5") +filepath = join(py4DSTEM._TESTPATH, "test_io/test_realslice_io.h5") def test_read_realslice(): realslice = py4DSTEM.read(filepath, datapath='4DSTEM/Fit Data') diff --git a/test/test_native_io/test_single_object_io.py b/test/test_native_io/test_single_object_io.py index 22ee2d0df..ae77b01cd 100644 --- a/test/test_native_io/test_single_object_io.py +++ b/test/test_native_io/test_single_object_io.py @@ -7,172 +7,67 @@ from py4DSTEM import save,read import emdfile as emd -from py4DSTEM.classes import ( +from py4DSTEM.data import ( DataCube, - BraggVectors, + Calibration, DiffractionSlice, - VirtualDiffraction, - Probe, RealSlice, - VirtualImage, QPoints, - Calibration ) +from py4DSTEM.process.diskdetection import BraggVectors +from py4DSTEM.classes import Probe, VirtualDiffraction, VirtualImage # Set paths dirpath = py4DSTEM._TESTPATH -path_dm3 = join(dirpath,"small_dm3.dm3") +path_dm3 = join(dirpath,"test_io/small_dm3_3Dstack.dm3") path_h5 = join(dirpath,"test.h5") +class TestDataCubeIO(): - -class TestSingleDataNodeIO: - - ## Setup and teardown - - @classmethod - def setup_class(cls): - cls._clear_files(cls) - cls._make_data(cls) - - @classmethod - def teardown_class(cls): - pass - - def setup_method(self, method): - pass - - def teardown_method(self, method): - self._clear_files() - - def _make_data(self): - """ Make - - a datacube - - a braggvectors instance with only v_uncal - - a braggvectors instance with both PLAs - - a diffractionslice - - a realslice - - a probe, with no kernel - - a probe, with a kernel - - a qpoints instance - - a virtualdiffraction instance - - a virtualimage instance + def test_datacube_instantiation(self): + """ + Instantiate a datacube and apply basic calibrations """ - # datacube - self.datacube = DataCube( + datacube = DataCube( data = np.arange(np.prod((4,5,6,7))).reshape((4,5,6,7)) ) # calibration - self.datacube.calibration.set_Q_pixel_size(0.062) - self.datacube.calibration.set_Q_pixel_units("A^-1") - self.datacube.calibration.set_R_pixel_size(2.8) - self.datacube.calibration.set_R_pixel_units("nm") - # braggvectors - self.braggvectors = BraggVectors( - Rshape = (5,6), - Qshape = (7,8) - ) - for x in range(self.braggvectors.Rshape[0]): - for y in range(self.braggvectors.Rshape[1]): - L = int(4 * (np.sin(x*y)+1)) - self.braggvectors.vectors_uncal[x,y].add( - np.ones(L,dtype=self.braggvectors.vectors_uncal.dtype) - ) - # braggvectors 2 - self.braggvectors2 = BraggVectors( - Rshape = (5,6), - Qshape = (7,8) - ) - for x in range(self.braggvectors2.Rshape[0]): - for y in range(self.braggvectors2.Rshape[1]): - L = int(4 * (np.sin(x*y)+1)) - self.braggvectors2.vectors_uncal[x,y].add( - np.ones(L,dtype=self.braggvectors2.vectors_uncal.dtype) - ) - self.braggvectors2._v_cal = self.braggvectors2._v_uncal.copy(name='_v_uncal') - # diffractionslice - self.diffractionslice = DiffractionSlice( - data = np.arange(np.prod((4,8,2))).reshape((4,8,2)), - slicelabels = ['a','b'] - ) - # realslice - self.realslice = RealSlice( - data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), - slicelabels = ['x','y'] - ) - # virtualdiffraction instance - self.virtualdiffraction = VirtualDiffraction( - data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), - ) - # virtualimage instance - self.virtualimage = VirtualImage( - data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), - ) - # probe, with no kernel - self.probe1 = Probe( - data = np.arange(8*12).reshape((8,12)) - ) - # probe, with a kernel - self.probe2 = Probe( - data = np.arange(8*12*2).reshape((8,12,2)) - ) - # qpoints instance - self.qpoints = QPoints( - data = np.ones(10, - dtype = [('qx',float),('qy',float),('intensity',float)] - ) - ) - - - - - - + datacube.calibration.set_Q_pixel_size(0.062) + datacube.calibration.set_Q_pixel_units("A^-1") + datacube.calibration.set_R_pixel_size(2.8) + datacube.calibration.set_R_pixel_units("nm") + return datacube - - def _clear_files(self): + def test_datacube_io(self): """ - Delete h5 files which this test suite wrote + Instantiate, save, then read a datacube, and + compare its contents before/after """ - paths = [ - path_h5 - ] - for p in paths: - if exists(p): - remove(p) - - - + datacube = self.test_datacube_instantiation() - - ## Tests - - def test_datacube(self): - """ Save then read a datacube, and compare its contents before/after - """ - assert(isinstance(self.datacube,DataCube)) + assert(isinstance(datacube,DataCube)) # test dim vectors - assert(self.datacube.dim_names[0] == 'Rx') - assert(self.datacube.dim_names[1] == 'Ry') - assert(self.datacube.dim_names[2] == 'Qx') - assert(self.datacube.dim_names[3] == 'Qy') - assert(self.datacube.dim_units[0] == 'nm') - assert(self.datacube.dim_units[1] == 'nm') - assert(self.datacube.dim_units[2] == 'A^-1') - assert(self.datacube.dim_units[3] == 'A^-1') - assert(self.datacube.dims[0][1] == 2.8) - assert(self.datacube.dims[2][1] == 0.062) + assert(datacube.dim_names[0] == 'Rx') + assert(datacube.dim_names[1] == 'Ry') + assert(datacube.dim_names[2] == 'Qx') + assert(datacube.dim_names[3] == 'Qy') + assert(datacube.dim_units[0] == 'nm') + assert(datacube.dim_units[1] == 'nm') + assert(datacube.dim_units[2] == 'A^-1') + assert(datacube.dim_units[3] == 'A^-1') + assert(datacube.dims[0][1] == 2.8) + assert(datacube.dims[2][1] == 0.062) # check the calibrations - assert(self.datacube.calibration.get_Q_pixel_size() == 0.062) - assert(self.datacube.calibration.get_Q_pixel_units() == "A^-1") + assert(datacube.calibration.get_Q_pixel_size() == 0.062) + assert(datacube.calibration.get_Q_pixel_units() == "A^-1") # save and read - save(path_h5,self.datacube) + save(path_h5,datacube,mode='o') new_datacube = read(path_h5) # check it's the same assert(isinstance(new_datacube,DataCube)) - assert(array_equal(self.datacube.data,new_datacube.data)) + assert(array_equal(datacube.data,new_datacube.data)) assert(new_datacube.calibration.get_Q_pixel_size() == 0.062) assert(new_datacube.calibration.get_Q_pixel_units() == "A^-1") assert(new_datacube.dims[0][1] == 2.8) @@ -180,137 +75,180 @@ def test_datacube(self): +class TestBraggVectorsIO(): - def test_braggvectors(self): - """ Save then read a BraggVectors instance, and compare contents before/after + def test_braggvectors_instantiation(self): """ - assert(isinstance(self.braggvectors,BraggVectors)) - # save then read - save(path_h5,self.braggvectors) - new_braggvectors = read(path_h5) - # check it's the same - assert(isinstance(new_braggvectors,BraggVectors)) - assert(new_braggvectors is not self.braggvectors) - for x in range(new_braggvectors.shape[0]): - for y in range(new_braggvectors.shape[1]): - assert(array_equal( - new_braggvectors.v_uncal[x,y].data, - self.braggvectors.v_uncal[x,y].data)) - # check that _v_cal isn't there - assert(not(hasattr(new_braggvectors,'_v_cal'))) + Instantiate a braggvectors instance + """ + braggvectors = BraggVectors( + Rshape = (5,6), + Qshape = (7,8) + ) + for x in range(braggvectors.Rshape[0]): + for y in range(braggvectors.Rshape[1]): + L = int(4 * (np.sin(x*y)+1)) + braggvectors._v_uncal[x,y].add( + np.ones(L,dtype=braggvectors._v_uncal.dtype) + ) + return braggvectors - def test_braggvectors2(self): + def test_braggvectors_io(self): """ Save then read a BraggVectors instance, and compare contents before/after """ - assert(isinstance(self.braggvectors2,BraggVectors)) + braggvectors = self.test_braggvectors_instantiation() + + assert(isinstance(braggvectors,BraggVectors)) # save then read - save(path_h5,self.braggvectors2) + save(path_h5,braggvectors,mode='o') new_braggvectors = read(path_h5) # check it's the same assert(isinstance(new_braggvectors,BraggVectors)) - assert(new_braggvectors is not self.braggvectors2) + assert(new_braggvectors is not braggvectors) for x in range(new_braggvectors.shape[0]): for y in range(new_braggvectors.shape[1]): assert(array_equal( - new_braggvectors.v_uncal[x,y].data, - self.braggvectors2.v_uncal[x,y].data)) - # check cal vectors are there - assert(hasattr(new_braggvectors,'_v_cal')) - # check it's the same - for x in range(new_braggvectors.shape[0]): - for y in range(new_braggvectors.shape[1]): - assert(array_equal( - new_braggvectors.v[x,y].data, - self.braggvectors2.v[x,y].data)) + new_braggvectors._v_uncal[x,y].data, + braggvectors._v_uncal[x,y].data)) + + +class TestSlices: - def test_diffractionslice(self): + # test instantiation + + def test_diffractionslice_instantiation(self): + diffractionslice = DiffractionSlice( + data = np.arange(np.prod((4,8,2))).reshape((4,8,2)), + slicelabels = ['a','b'] + ) + return diffractionslice + + def test_realslice_instantiation(self): + realslice = RealSlice( + data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), + slicelabels = ['x','y'] + ) + return realslice + + def test_virtualdiffraction_instantiation(self): + virtualdiffraction = VirtualDiffraction( + data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), + ) + return virtualdiffraction + + def test_virtualimage_instantiation(self): + virtualimage = VirtualImage( + data = np.arange(np.prod((8,4,2))).reshape((8,4,2)), + ) + return virtualimage + + def test_probe_instantiation(self): + probe = Probe( + data = np.arange(8*12).reshape((8,12)) + ) + # add a kernel + probe.kernel = np.ones_like(probe.probe) + # return + return probe + + + # test io + + def test_diffractionslice_io(self): """ test diffractionslice io """ - assert(isinstance(self.diffractionslice,DiffractionSlice)) + diffractionslice = self.test_diffractionslice_instantiation() + assert(isinstance(diffractionslice,DiffractionSlice)) # save and read - save(path_h5,self.diffractionslice) - diffractionslice = read(path_h5) + save(path_h5,diffractionslice,mode='o') + new_diffractionslice = read(path_h5) # check it's the same - assert(isinstance(diffractionslice,DiffractionSlice)) - assert(array_equal(self.diffractionslice.data,diffractionslice.data)) - assert(diffractionslice.slicelabels == self.diffractionslice.slicelabels) + assert(isinstance(new_diffractionslice,DiffractionSlice)) + assert(array_equal(diffractionslice.data,new_diffractionslice.data)) + assert(diffractionslice.slicelabels == new_diffractionslice.slicelabels) - def test_realslice(self): + def test_realslice_io(self): """ test realslice io """ - assert(isinstance(self.realslice,RealSlice)) + realslice = self.test_realslice_instantiation() + assert(isinstance(realslice,RealSlice)) # save and read - save(path_h5,self.realslice) + save(path_h5,realslice,mode='o') rs = read(path_h5) # check it's the same assert(isinstance(rs,RealSlice)) - assert(array_equal(self.realslice.data,rs.data)) - assert(rs.slicelabels == self.realslice.slicelabels) + assert(array_equal(realslice.data,rs.data)) + assert(rs.slicelabels == realslice.slicelabels) - def test_virtualdiffraction(self): + def test_virtualdiffraction_io(self): """ test virtualdiffraction io """ - assert(isinstance(self.virtualdiffraction,VirtualDiffraction)) + virtualdiffraction = self.test_virtualdiffraction_instantiation() + assert(isinstance(virtualdiffraction,VirtualDiffraction)) # save and read - save(path_h5,self.virtualdiffraction) - virtualdiffraction = read(path_h5) + save(path_h5,virtualdiffraction,mode='o') + vd = read(path_h5) # check it's the same - assert(isinstance(virtualdiffraction,VirtualDiffraction)) - assert(array_equal(self.virtualdiffraction.data,virtualdiffraction.data)) + assert(isinstance(vd,VirtualDiffraction)) + assert(array_equal(vd.data,virtualdiffraction.data)) pass - def test_virtualimage(self): + def test_virtualimage_io(self): """ test virtualimage io """ - assert(isinstance(self.virtualimage,VirtualImage)) + virtualimage = self.test_virtualimage_instantiation() + assert(isinstance(virtualimage,VirtualImage)) # save and read - save(path_h5,self.virtualimage) + save(path_h5,virtualimage,mode='o') virtIm = read(path_h5) # check it's the same assert(isinstance(virtIm,VirtualImage)) - assert(array_equal(self.virtualimage.data,virtIm.data)) + assert(array_equal(virtualimage.data,virtIm.data)) pass - def test_probe1(self): - """ test probe io - """ - assert(isinstance(self.probe1,Probe)) - # check for an empty kernel array - assert(array_equal(self.probe1.kernel,np.zeros_like(self.probe1.probe))) - # save and read - save(path_h5,self.probe1) - probe = read(path_h5) - # check it's the same - assert(isinstance(probe,Probe)) - assert(array_equal(self.probe1.data,probe.data)) - pass - def test_probe2(self): + def test_probe1_io(self): """ test probe io """ - assert(isinstance(self.probe2,Probe)) + probe0 = self.test_probe_instantiation() + assert(isinstance(probe0,Probe)) # save and read - save(path_h5,self.probe2) + save(path_h5,probe0,mode='o') probe = read(path_h5) # check it's the same assert(isinstance(probe,Probe)) - assert(array_equal(self.probe2.data,probe.data)) + assert(array_equal(probe0.data,probe.data)) pass - def test_qpoints(self): + + + +class TestPoints: + + def test_qpoints_instantiation(self): + qpoints = QPoints( + data = np.ones(10, + dtype = [('qx',float),('qy',float),('intensity',float)] + ) + ) + return qpoints + + + def test_qpoints_io(self): """ test qpoints io """ - assert(isinstance(self.qpoints,QPoints)) + qpoints0 = self.test_qpoints_instantiation() + assert(isinstance(qpoints0,QPoints)) # save and read - save(path_h5,self.qpoints) + save(path_h5,qpoints0,mode='o') qpoints = read(path_h5) # check it's the same assert(isinstance(qpoints,QPoints)) - assert(array_equal(self.qpoints.data,qpoints.data)) + assert(array_equal(qpoints0.data,qpoints.data)) pass diff --git a/test/test_native_io/test_v0_13.py b/test/test_native_io/test_v0_13.py index b3fa0328d..92ab41ca2 100644 --- a/test/test_native_io/test_v0_13.py +++ b/test/test_native_io/test_v0_13.py @@ -3,7 +3,7 @@ # Set filepaths -filepath = join(_TESTPATH, "v13_sample.h5") +filepath = join(_TESTPATH, "test_io/legacy_v0.13.h5") diff --git a/test/test_native_io/test_v0_14.py b/test/test_native_io/test_v0_14.py index c6ba27ea8..33230a816 100644 --- a/test/test_native_io/test_v0_14.py +++ b/test/test_native_io/test_v0_14.py @@ -3,7 +3,7 @@ -path = join(py4DSTEM._TESTPATH,'test_v14_sample.h5') +path = join(py4DSTEM._TESTPATH,'test_io/legacy_v0.14.h5') @@ -14,7 +14,7 @@ def _make_v14_test_file(): assert(py4DSTEM.__version__.split('.')[1]=='14'), 'no!' # Set filepaths - filepath_data = join(py4DSTEM._TESTPATH,"simulatedAuNanoplatelet_binned_v0_9.h5") + filepath_data = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") # Read sim Au datacube datacube = py4DSTEM.io.read( diff --git a/test/test_native_io/test_v0_9.py b/test/test_native_io/test_v0_9.py index b3424efa4..8024f646c 100644 --- a/test/test_native_io/test_v0_9.py +++ b/test/test_native_io/test_v0_9.py @@ -1,7 +1,7 @@ from py4DSTEM import read, DataCube, _TESTPATH from os.path import join -path = join(_TESTPATH, 'simulatedAuNanoplatelet_binned_v0_9.h5') +path = join(_TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") def test_read_v0_9_noID(): diff --git a/test/test_nonnative_io/test_dm.py b/test/test_nonnative_io/test_dm.py index 9fd311579..a3d5aa7b0 100644 --- a/test/test_nonnative_io/test_dm.py +++ b/test/test_nonnative_io/test_dm.py @@ -5,7 +5,7 @@ # Set filepaths filepath_dm4_datacube = join(py4DSTEM._TESTPATH, "small_datacube.dm4") -filepath_dm3_3Dstack = join(py4DSTEM._TESTPATH, "io_test_data/small_dm3_3Dstack.dm3") +filepath_dm3_3Dstack = join(py4DSTEM._TESTPATH, "test_io/small_dm3_3Dstack.dm3") def test_dmfile_datacube(): diff --git a/test/test_workflow/test_basics.py b/test/test_workflow/test_basics.py index 083b15fcb..cb30f5d6c 100644 --- a/test/test_workflow/test_basics.py +++ b/test/test_workflow/test_basics.py @@ -2,7 +2,7 @@ from os.path import join # set filepath -path = join(py4DSTEM._TESTPATH,"simulatedAuNanoplatelet_binned_v0_9.h5") +path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") diff --git a/test/test_workflow/test_disk_detection_basic.py b/test/test_workflow/test_disk_detection_basic.py index 18296d0a7..058fb67ee 100644 --- a/test/test_workflow/test_disk_detection_basic.py +++ b/test/test_workflow/test_disk_detection_basic.py @@ -3,7 +3,7 @@ from numpy import zeros # set filepath -path = join(py4DSTEM._TESTPATH,"simulatedAuNanoplatelet_binned_v0_9.h5") +path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") diff --git a/test/test_workflow/test_disk_detection_with_calibration.py b/test/test_workflow/test_disk_detection_with_calibration.py index 83e52050f..c1bb4a581 100644 --- a/test/test_workflow/test_disk_detection_with_calibration.py +++ b/test/test_workflow/test_disk_detection_with_calibration.py @@ -3,7 +3,7 @@ from numpy import zeros # set filepath -path = join(py4DSTEM._TESTPATH,"simulatedAuNanoplatelet_binned_v0_9.h5") +path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") From 36e2061e08e338c968da65163e2525accc916260 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 27 Jun 2023 18:48:25 -0400 Subject: [PATCH 076/362] bugfixes --- py4DSTEM/data/calibration.py | 2 +- py4DSTEM/data/datacube.py | 4 ++-- py4DSTEM/data/propagating_calibration.py | 2 +- py4DSTEM/io/read.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index a9937612d..1fd6fd492 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -211,7 +211,7 @@ def __init__( # EMD root property @property def root(self): - return _root + return self._root @root.setter def root(self): raise Exception("Calibration.root does not support assignment; to change the root, use self.set_root") diff --git a/py4DSTEM/data/datacube.py b/py4DSTEM/data/datacube.py index 775ca75a8..461787b6a 100644 --- a/py4DSTEM/data/datacube.py +++ b/py4DSTEM/data/datacube.py @@ -139,12 +139,12 @@ def qxxs(self,rx,ry): qx0_shift = self.calibration.get_qx0shift(rx,ry) if qx0_shift is None: raise Exception("Can't compute shifted meshgrid - origin shift is not defined") - return qxx - qx0_shift + return self.qxx - qx0_shift def qyys(self,rx,ry): qy0_shift = self.calibration.get_qy0shift(rx,ry) if qy0_shift is None: raise Exception("Can't compute shifted meshgrid - origin shift is not defined") - return qyy - qy0_shift + return self.qyy - qy0_shift diff --git a/py4DSTEM/data/propagating_calibration.py b/py4DSTEM/data/propagating_calibration.py index fa34f1468..a80382338 100644 --- a/py4DSTEM/data/propagating_calibration.py +++ b/py4DSTEM/data/propagating_calibration.py @@ -26,7 +26,7 @@ def __call__(self, *args, **kwargs): some_object = args[0] assert hasattr(some_object, "_targets"), "SomeObject object appears to be in an invalid state. _targets attribute is missing." for target in some_object._targets: - if hasattr(target,'method') and callable(target,method): + if hasattr(target,'method') and callable(target.method): try: target.method() except Exception as err: diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index a28d06e16..589486040 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -108,7 +108,7 @@ def read( d = data.root.tree(p) cal.register_target( d ) if hasattr(d,'setcal'): - dsetcal() + d.setcal() except KeyError: pass cal.calibrate() From ad3f334898b45cdcff27e9fee78b8565d483d8c0 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 28 Jun 2023 13:13:34 -0400 Subject: [PATCH 077/362] update cupy min version to 10.0.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f518599cc..bc38d2419 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ ], extras_require={ 'ipyparallel': ['ipyparallel >= 6.2.4', 'dill >= 0.3.3'], - 'cuda': ['cupy'], + 'cuda': ['cupy >= 10.0.0'], 'acom': ['pymatgen >= 2022', 'mp-api == 0.24.1'], 'aiml': ['tensorflow == 2.4.1','tensorflow-addons <= 0.14.0','crystal4D'], 'aiml-cuda': ['tensorflow == 2.4.1','tensorflow-addons <= 0.14.0','crystal4D','cupy'], From 621401e26c0017875676bedc2e064118a640ab9e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 28 Jun 2023 17:37:03 -0400 Subject: [PATCH 078/362] rms Probe from classes, ->diskdection, all tests passing --- py4DSTEM/__init__.py | 2 +- py4DSTEM/classes/__init__.py | 1 - py4DSTEM/classes/methods/__init__.py | 2 - py4DSTEM/classes/methods/probe_methods.py | 76 --- py4DSTEM/classes/probe.py | 84 --- py4DSTEM/data/calibration.py | 12 +- py4DSTEM/data/data.py | 21 +- py4DSTEM/data/datacube.py | 138 ++-- py4DSTEM/data/diffractionslice.py | 10 +- py4DSTEM/data/realslice.py | 8 +- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 3 +- py4DSTEM/process/__init__.py | 2 - py4DSTEM/process/diskdetection/__init__.py | 1 + .../process/diskdetection/braggvectors.py | 2 + py4DSTEM/process/diskdetection/probe.py | 608 ++++++++++++++++++ .../probe_gen_methods.py} | 119 ---- py4DSTEM/process/probe/__init__.py | 3 - py4DSTEM/process/probe/kernel.py | 279 -------- test/test_braggvectors.py | 2 +- test/test_native_io/test_single_object_io.py | 4 +- test/test_probe.py | 65 ++ .../test_disk_detection_basic.py | 2 +- .../test_disk_detection_with_calibration.py | 2 +- 23 files changed, 812 insertions(+), 634 deletions(-) delete mode 100644 py4DSTEM/classes/methods/__init__.py delete mode 100644 py4DSTEM/classes/methods/probe_methods.py delete mode 100644 py4DSTEM/classes/probe.py create mode 100644 py4DSTEM/process/diskdetection/probe.py rename py4DSTEM/process/{probe/probe.py => diskdetection/probe_gen_methods.py} (69%) delete mode 100644 py4DSTEM/process/probe/__init__.py delete mode 100644 py4DSTEM/process/probe/kernel.py create mode 100644 test/test_probe.py diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index f01604896..de56213d0 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -25,9 +25,9 @@ from py4DSTEM.classes import ( VirtualDiffraction, VirtualImage, - Probe, ) from py4DSTEM.process.diskdetection import ( + Probe, BraggVectors, BraggVectorMap, ) diff --git a/py4DSTEM/classes/__init__.py b/py4DSTEM/classes/__init__.py index d97b413d9..750c8a9bb 100644 --- a/py4DSTEM/classes/__init__.py +++ b/py4DSTEM/classes/__init__.py @@ -1,6 +1,5 @@ _emd_hook = True -from py4DSTEM.classes.probe import Probe from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction from py4DSTEM.classes.virtualimage import VirtualImage diff --git a/py4DSTEM/classes/methods/__init__.py b/py4DSTEM/classes/methods/__init__.py deleted file mode 100644 index a2455dba3..000000000 --- a/py4DSTEM/classes/methods/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from py4DSTEM.classes.methods.probe_methods import ProbeMethods - diff --git a/py4DSTEM/classes/methods/probe_methods.py b/py4DSTEM/classes/methods/probe_methods.py deleted file mode 100644 index 9fd040ff6..000000000 --- a/py4DSTEM/classes/methods/probe_methods.py +++ /dev/null @@ -1,76 +0,0 @@ -# Functions to become Probe methods - -import numpy as np - - - -class ProbeMethods: - """ - A container for Probe object instance methods. - """ - - def __init__(self): - pass - - - - # Kernel generation - - def get_kernel( - self, - mode = 'flat', - returncalc = True, - **kwargs - ): - """ - Creates a kernel from the probe for cross-correlative template matching. - - Precise behavior and valid keyword arguments depend on the `mode` - selected. In each case, the center of the probe is shifted to the - origin and the kernel normalized such that it sums to 1. In 'flat' - mode, this is the only processing performed. In the remaining modes, - some additional processing is performed which adds a ring of - negative intensity around the central probe, which results in - edge-filetering-like behavior during cross correlation. Valid modes, - and the required additional kwargs, if any, for each, are: - - - 'flat': creates a flat probe kernel. For bullseye or other - structured probes, this mode is recommended. No required - arguments, optional arg `origin` (2 tuple) - - 'gaussian': subtracts a gaussian with a width of standard - deviation `sigma`, which is a required argument. Optional - arg `origin`. - - 'sigmoid': subtracts an annulus with inner and outer radii - of (ri,ro) and a sine-squared sigmoid radial profile from - the probe template. Required arg: `radii` (2 tuple). Optional - args `origin` (2-tuple) - - 'sigmoid_log': subtracts an annulus with inner and outer radii - of (ri,ro) and a logistic sigmoid radial profile from - the probe template. Required arg: `radii` (2 tuple). Optional - args `origin` (2-tuple) - - Returns: - (2D array) - """ - - # perform computation - from py4DSTEM.process.probe import get_kernel - kern = get_kernel( - self.probe, - mode = mode, - **kwargs - ) - - # add to the Probe - self.kernel = kern - - # return - if returncalc: - return kern - - - - - - - diff --git a/py4DSTEM/classes/probe.py b/py4DSTEM/classes/probe.py deleted file mode 100644 index 53eaa3298..000000000 --- a/py4DSTEM/classes/probe.py +++ /dev/null @@ -1,84 +0,0 @@ - -from py4DSTEM.data import DiffractionSlice, Data -from py4DSTEM.classes.methods import ProbeMethods - -from typing import Optional -import numpy as np - -class Probe(DiffractionSlice,ProbeMethods,Data): - """ - Stores a vacuum probe. - """ - - def __init__( - self, - data: np.ndarray, - name: Optional[str] = 'probe' - ): - """ - Accepts: - data (2D or 3D np.ndarray): the vacuum probe, or - the vacuum probe + kernel - name (str): a name - - Returns: - (Probe) - """ - # if only the probe is passed, make space for the kernel - if data.ndim == 2: - data = np.stack([ - data, - np.zeros_like(data) - ]) - - # initialize as a ProbeMethods instance - super(ProbeMethods).__init__() - - # initialize as a DiffractionSlice - DiffractionSlice.__init__( - self, - name = name, - data = data, - slicelabels = [ - 'probe', - 'kernel' - ] - ) - - - ## properties - - @property - def probe(self): - return self.get_slice('probe').data - @probe.setter - def probe(self,x): - assert(x.shape == (self.data.shape[1:])) - self.data[0,:,:] = x - @property - def kernel(self): - return self.get_slice('kernel').data - @kernel.setter - def kernel(self,x): - assert(x.shape == (self.data.shape[1:])) - self.data[1,:,:] = x - - - - - # read - @classmethod - def _get_constructor_args(cls,group): - """ - Returns a dictionary of args/values to pass to the class constructor - """ - ar_constr_args = DiffractionSlice._get_constructor_args(group) - args = { - 'data' : ar_constr_args['data'], - 'name' : ar_constr_args['name'], - } - return args - - - - diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index 1fd6fd492..e2fe0c393 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -159,13 +159,13 @@ class Calibration(Metadata): Attaching an object to a different Calibration ---------------------------------------------- - To modify the calibration associated with an object's `data`, use + To modify the calibration associated with some object `data`, use >>> c.attach( data ) - where `c` is the new calibration instance `data` is to be associated - with. This (1) moves `data` into the top level of `c`'s data tree, - which means the new calibration will now be accessible normally at + where `c` is the new calibration instance. This (1) moves `data` into the + top level of `c`'s data tree, which means the new calibration will now be + accessible normally at >>> data.calibration @@ -176,7 +176,7 @@ class Calibration(Metadata): called. To attach `data` to a different location in the calibration instance's - tree, use `data.attach( node )`. See the Data.attach docstring. + tree, use `node.attach( data )`. See the Data.attach docstring. """ def __init__( self, @@ -232,7 +232,7 @@ def attach(self,data): """ from py4DSTEM.data import Data assert(isinstance(data,Data)), f"data must be a Data instance" - data.attach(self.root) + self.root.attach(data) # Register for auto-calibration diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index c2c4aef50..ba82f4fec 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -107,17 +107,22 @@ def calibration(self, x): def attach(self,node): """ - Moves self to `node`'s tree, attaching to node's calibration and detaching - from the current calibration. + Attach `node` to the current object's tree, attaching calibration and detaching + calibrations as needed. """ assert(isinstance(node,Node)), f"node must be a Node, not type {type(node)}" - assert(hasattr(node,'calibration')), "node must have a calibration" - if self in self.calibration._targets: - register = True - self.calibration.unregister_target(self) - node.graft(self) + register = False + if hasattr(node,'calibration'): + if node.calibration is not None: + if node in node.calibration._targets: + register = True + node.calibration.unregister_target(node) + if node.root is None: + self.tree(node) + else: + self.graft(node) if register: - self.calibration.register_target(self) + self.calibration.register_target(node) diff --git a/py4DSTEM/data/datacube.py b/py4DSTEM/data/datacube.py index 461787b6a..dc19a9443 100644 --- a/py4DSTEM/data/datacube.py +++ b/py4DSTEM/data/datacube.py @@ -3,9 +3,11 @@ import numpy as np from scipy.ndimage import distance_transform_edt, binary_fill_holes, gaussian_filter1d from scipy.interpolate import interp1d +from scipy.ndimage import ( + binary_opening, binary_dilation, distance_transform_edt) from typing import Optional,Union -from emdfile import Array, Metadata, Node, Root +from emdfile import Array, Metadata, Node, Root, tqdmnd from py4DSTEM.data import Data, Calibration @@ -329,7 +331,7 @@ def add( data = data, name = name ) - self.tree( data ) + self.attach( data ) def set_scan_shape( self, @@ -640,7 +642,7 @@ def get_virtual_diffraction( ) # add to the tree - self.tree( dp ) + self.attach( dp ) # return if returncalc: @@ -738,7 +740,7 @@ def get_dp_max( ) # add to the tree - self.tree( dp ) + self.attach( dp ) # return if returncalc: @@ -837,7 +839,7 @@ def get_dp_mean( ) # add to the tree - self.tree( dp ) + self.attach( dp ) # return if returncalc: @@ -933,7 +935,7 @@ def get_dp_median( ) # add to the tree - self.tree( dp ) + self.attach( dp ) # return if returncalc: @@ -1059,7 +1061,7 @@ def get_virtual_image( ) # add to the tree - self.tree( im ) + self.attach( im ) # return if returncalc: @@ -1141,50 +1143,98 @@ def position_detector( def get_vacuum_probe( self, ROI = None, - name = 'probe', - returncalc = True, + align = True, + mask = None, + threshold = 0.2, + expansion = 12, + opening = 3, + verbose = False, + returncalc = True ): """ - Computes a vacuum probe from the DataCube by aligning and averaging - either all or some subset of the diffraction patterns. + Computes a vacuum probe. - Args: - ROI (None or boolean array or tuple): if None, uses the whole - datacube. Otherwise, uses a subset of diffraction patterns. - If `ROI` is a boolean array, it should be Rspace shaped, and - diffraction patterns where True are used. Else should be - a 4-tuple representing (Rxmin,Rxmax,Rymin,Rymax) of a - rectangular region to use. + Which diffraction patterns are included in the calculation is specified + by the `ROI` parameter. Diffraction patterns are aligned before averaging + if `align` is True (default). A global mask is applied to each diffraction + pattern before aligning/averaging if `mask` is specified. After averaging, + a final masking step is applied according to the parameters `threshold`, + `expansion`, and `opening`. - Returns: - (Probe) a Probe instance + Parameters + ---------- + ROI : optional, boolean array or len 4 list/tuple + If unspecified, uses the whole datacube. If a boolean array is + passed must be real-space shaped, and True pixels are used. If a + 4-tuple is passed, uses the region inside the limits + (rx_min,rx_max,ry_min,ry_max) + align : optional, bool + if True, aligns the probes before averaging + mask : optional, array + mask applied to each diffraction pattern before alignment and + averaging + threshold : float + in the final masking step, values less than max(probe)*threshold + are considered outside the probe + expansion : int + number of pixels by which the final mask is expanded after + thresholding + opening : int + size of binary opening applied to the final mask to eliminate stray + bright pixels + verbose : bool + toggles verbose output + returncalc : bool + if True, returns the answer + Returns + ------- + probe : Probe, optional + the vacuum probe """ + from py4DSTEM.process.utils import get_shifted_ar, get_shift + from py4DSTEM.process.diskdetection import Probe - # perform computation - from py4DSTEM.classes.probe import Probe - from py4DSTEM.process.probe import get_vacuum_probe + # parse region to use if ROI is None: - x = get_vacuum_probe( - self - ) + ROI = np.ones(self.Rshape,dtype=bool) + elif isinstance(ROI,tuple): + assert(len(ROI)==4), "if ROI is a tuple must be length 4" + _ROI = np.ones(self.Rshape,dtype=bool) + ROI = _ROI[ROI[0]:ROI[1],ROI[2]:ROI[3]] else: - x = get_vacuum_probe( - self, - ROI = ROI - ) - - # wrap with a py4dstem class - x = Probe( - data = x - ) - - # add to the tree - self.tree( x ) - - # return + assert(isinstance(ROI,np.ndarray)) + assert(ROI.shape == self.Rshape) + xy = np.vstack(np.nonzero(ROI)) + length = xy.shape[1] + + # setup global mask + if mask is None: + mask = 1 + else: + assert(mask.shape == self.Qshape) + + # compute average probe + probe = self.data[xy[0,0],xy[1,0],:,:] + for n in tqdmnd(range(1,length)): + curr_DP = self.data[xy[0,n],xy[1,n],:,:] * mask + if align: + xshift,yshift = get_shift(probe, curr_DP) + curr_DP = get_shifted_ar(curr_DP, xshift, yshift) + probe = probe*(n-1)/n + curr_DP/n + + # mask + mask = probe > np.max(probe)*threshold + mask = binary_opening(mask, iterations=opening) + mask = binary_dilation(mask, iterations=1) + mask = np.cos((np.pi/2)*np.minimum(distance_transform_edt(np.logical_not(mask)) / expansion, 1))**2 + probe *= mask + + # make a probe, add to tree, and return + probe = Probe(probe) + self.attach(probe) if returncalc: - return x + return probe @@ -1248,7 +1298,7 @@ def get_probe_size( DP = self.tree( 'dp_mean' ).data elif type(dp) == str: assert dp in self._branch.keys(), "mode not found" - DP = self.tree( dp ) + DP = self.attach( dp ) elif type(dp) == np.ndarray: assert len(dp.shape) == 2, "must be a 2D array" DP = dp @@ -1540,7 +1590,7 @@ def find_Bragg_disks( # add to tree if data is None: - self.tree( peaks ) + self.attach( peaks ) # return if returncalc: @@ -1626,7 +1676,7 @@ def get_beamstop_mask( ) # Add to tree - self.tree( mask_beamstop ) + self.attach( mask_beamstop ) # return if returncalc: diff --git a/py4DSTEM/data/diffractionslice.py b/py4DSTEM/data/diffractionslice.py index ece658adc..40104cf80 100644 --- a/py4DSTEM/data/diffractionslice.py +++ b/py4DSTEM/data/diffractionslice.py @@ -18,7 +18,8 @@ def __init__( data: np.ndarray, name: Optional[str] = 'diffractionslice', units: Optional[str] = 'intensity', - slicelabels: Optional[Union[bool,list]] = None + slicelabels: Optional[Union[bool,list]] = None, + calibration = None ): """ Accepts: @@ -39,6 +40,13 @@ def __init__( units = units, slicelabels = slicelabels ) + # initialize as Data + Data.__init__( + self, + calibration + ) + + # read diff --git a/py4DSTEM/data/realslice.py b/py4DSTEM/data/realslice.py index 0a2f893c9..205cbc1ab 100644 --- a/py4DSTEM/data/realslice.py +++ b/py4DSTEM/data/realslice.py @@ -17,7 +17,8 @@ def __init__( data: np.ndarray, name: Optional[str] = 'realslice', units: Optional[str] = 'intensity', - slicelabels: Optional[Union[bool,list]] = None + slicelabels: Optional[Union[bool,list]] = None, + calibration = None ): """ Accepts: @@ -37,6 +38,11 @@ def __init__( units = 'intensity', slicelabels = slicelabels ) + # initialize as Data + Data.__init__( + self, + calibration + ) # read diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 453c4cf1c..9bafe15d2 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -46,9 +46,8 @@ from py4DSTEM.classes import ( VirtualImage, VirtualDiffraction, - Probe, ) -from py4DSTEM.process.diskdetection.braggvectors import BraggVectors +from py4DSTEM.process.diskdetection import BraggVectors, Probe diff --git a/py4DSTEM/process/__init__.py b/py4DSTEM/process/__init__.py index 841314fbb..da88ec4ba 100644 --- a/py4DSTEM/process/__init__.py +++ b/py4DSTEM/process/__init__.py @@ -3,10 +3,8 @@ from py4DSTEM.process import diskdetection from py4DSTEM.process import virtualdiffraction from py4DSTEM.process import virtualimage -from py4DSTEM.process import probe from py4DSTEM.process import latticevectors from py4DSTEM.process import phase -from py4DSTEM.process import probe from py4DSTEM.process import calibration from py4DSTEM.process import utils from py4DSTEM.process import classification diff --git a/py4DSTEM/process/diskdetection/__init__.py b/py4DSTEM/process/diskdetection/__init__.py index 76b0ea25c..9d42a2ad5 100644 --- a/py4DSTEM/process/diskdetection/__init__.py +++ b/py4DSTEM/process/diskdetection/__init__.py @@ -1,3 +1,4 @@ +from py4DSTEM.process.diskdetection.probe import Probe from py4DSTEM.process.diskdetection.braggvectors import BraggVectors from py4DSTEM.process.diskdetection.braggvector_methods import BraggVectorMap from py4DSTEM.process.diskdetection.diskdetection import * diff --git a/py4DSTEM/process/diskdetection/braggvectors.py b/py4DSTEM/process/diskdetection/braggvectors.py index 3130e2c76..15b326475 100644 --- a/py4DSTEM/process/diskdetection/braggvectors.py +++ b/py4DSTEM/process/diskdetection/braggvectors.py @@ -53,8 +53,10 @@ def __init__( Qshape, name = 'braggvectors', verbose = True, + calibration = None ): Custom.__init__(self,name=name) + Data.__init__(self,calibration=calibration) self.Rshape = Rshape self.shape = self.Rshape diff --git a/py4DSTEM/process/diskdetection/probe.py b/py4DSTEM/process/diskdetection/probe.py new file mode 100644 index 000000000..4952044fa --- /dev/null +++ b/py4DSTEM/process/diskdetection/probe.py @@ -0,0 +1,608 @@ +# Defines the Probe class + +import numpy as np +from typing import Optional + +from py4DSTEM.data import DiffractionSlice, Data +from py4DSTEM.process.calibration import get_probe_size +from py4DSTEM.process.utils import get_CoM, get_shifted_ar +from scipy.ndimage import ( + binary_opening, binary_dilation, distance_transform_edt) + + + +class Probe(DiffractionSlice,Data): + """ + Stores a vacuum probe. + + Both a vacuum probe and a kernel for cross-correlative template matching + derived from that probe are stored and can be accessed at + + >>> p.probe + >>> p.kernel + + respectively, for some Probe instance `p`. If a kernel has not been computed + the latter expression returns None. + + + """ + + def __init__( + self, + data: np.ndarray, + name: Optional[str] = 'probe' + ): + """ + Accepts: + data (2D or 3D np.ndarray): the vacuum probe, or + the vacuum probe + kernel + name (str): a name + + Returns: + (Probe) + """ + # if only the probe is passed, make space for the kernel + if data.ndim == 2: + data = np.stack([ + data, + np.zeros_like(data) + ]) + + # initialize as a DiffractionSlice + DiffractionSlice.__init__( + self, + name = name, + data = data, + slicelabels = [ + 'probe', + 'kernel' + ] + ) + + + ## properties + + @property + def probe(self): + return self.get_slice('probe').data + @probe.setter + def probe(self,x): + assert(x.shape == (self.data.shape[1:])) + self.data[0,:,:] = x + @property + def kernel(self): + return self.get_slice('kernel').data + @kernel.setter + def kernel(self,x): + assert(x.shape == (self.data.shape[1:])) + self.data[1,:,:] = x + + + # read + @classmethod + def _get_constructor_args(cls,group): + """ + Returns a dictionary of args/values to pass to the class constructor + """ + ar_constr_args = DiffractionSlice._get_constructor_args(group) + args = { + 'data' : ar_constr_args['data'], + 'name' : ar_constr_args['name'], + } + return args + + + + # generation methods + + @classmethod + def from_vacuum_data( + cls, + data, + mask = None, + threshold = 0.2, + expansion = 12, + opening = 3 + ): + """ + Generates and returns a vacuum probe Probe instance from either a + 2D vacuum image or a 3D stack of vacuum diffraction patterns. + + The probe is multiplied by `mask`, if it's passed. An additional + masking step zeros values outside of a mask determined by `threshold`, + `expansion`, and `opening`, generated by first computing the binary image + probe < max(probe)*threshold, then applying a binary expansion and + then opening to this image. No alignment is performed - i.e. it is assumed + that the beam was stationary during acquisition of the stack. To align + the images, use the DataCube .get_vacuum_probe method. + + Parameters + ---------- + data : 2D or 3D array + the vacuum diffraction data. For 3D stacks, use shape (N,Q_Nx,Q_Ny) + mask : boolean array, optional + mask applied to the probe + threshold : float + threshold determining mask which zeros values outside of probe + expansion : int + number of pixels by which the zeroing mask is expanded to capture + the full probe + opening : int + size of binary opening used to eliminate stray bright pixels + + Returns + ------- + probe : Probe + the vacuum probe + """ + assert(isinstance(data,np.ndarray)) + if data.ndim == 3: + probe = np.average(data,axis=0) + elif data.ndim == 2: + probe = data + else: + raise Exception(f"data must be 2- or 3-D, not {data.ndim}-D") + + if mask is not None: + probe *= mask + + mask = probe > np.max(probe)*threshold + mask = binary_opening(mask, iterations=opening) + mask = binary_dilation(mask, iterations=1) + mask = np.cos((np.pi/2)*np.minimum( + distance_transform_edt(np.logical_not(mask)) / expansion, 1))**2 + + probe = cls(probe*mask) + return probe + + + @classmethod + def generate_synthetic_probe( + cls, + radius, + width, + Qshape + ): + """ + Makes a synthetic probe, with the functional form of a disk blurred by a + sigmoid (a logistic function). + + Parameters + ---------- + radius : float + the probe radius + width : float + the blurring of the probe edge. width represents the + full width of the blur, with x=-w/2 to x=+w/2 about the edge + spanning values of ~0.12 to 0.88 + Qshape : 2 tuple + the diffraction plane dimensions + + Returns + ------- + probe : Probe + the probe + """ + # Make coords + Q_Nx,Q_Ny = Qshape + qy,qx = np.meshgrid(np.arange(Q_Ny),np.arange(Q_Nx)) + qy,qx = qy - Q_Ny/2., qx-Q_Nx/2. + qr = np.sqrt(qx**2+qy**2) + + # Shift zero to disk edge + qr = qr - radius + + # Calculate logistic function + probe = 1/(1+np.exp(4*qr/width)) + + return cls(probe) + + + + # calibration methods + + def measure_disk( + self, + thresh_lower=0.01, + thresh_upper=0.99, + N=100, + returncalc=True, + data=None, + ): + """ + Finds the center and radius of an average probe image. + + A naive algorithm. Creates a series of N binary masks by thresholding + the probe image a linspace of N thresholds from thresh_lower to + thresh_upper, relative to the image max/min. For each mask, we find the + square root of the number of True valued pixels divided by pi to + estimate a radius. Because the central disk is intense relative to the + remainder of the image, the computed radii are expected to vary very + little over a wider range threshold values. A range of r values + considered trustworthy is estimated by taking the derivative + r(thresh)/dthresh identifying where it is small, and the mean of this + range is returned as the radius. A center is estimated using a binary + thresholded image in combination with the center of mass operator. + + Parameters + ---------- + thresh_lower : float, 0 to 1 + the lower limit of threshold values + thresh_upper : float, 0 to 1) + the upper limit of threshold values + N : int + the number of thresholds / masks to use + returncalc : True + toggles returning the answer + data : 2d array, optional + if passed, uses this 2D array in place of the probe image when + performing the computation. This also supresses storing the + results in the Probe's calibration metadata + + Returns + ------- + r, x0, y0 : (3-tuple) + the radius and origin + """ + # set the image + im = self.probe if data is None else data + + # define the thresholds + thresh_vals = np.linspace(thresh_lower, thresh_upper, N) + r_vals = np.zeros(N) + + # get binary images and compute a radius for each + immax = np.max(im) + for i,val in enumerate(thresh_vals): + mask = im > immax * val + r_vals[i] = np.sqrt(np.sum(mask) / np.pi) + + # Get derivative and determine trustworthy r-values + dr_dtheta = np.gradient(r_vals) + mask = (dr_dtheta <= 0) * (dr_dtheta >= 2 * np.median(dr_dtheta)) + r = np.mean(r_vals[mask]) + + # Get origin + thresh = np.mean(thresh_vals[mask]) + mask = im > immax * thresh + x0, y0 = get_CoM(im * mask) + + # Store metadata and return + ans = r,x0,y0 + if data is None: + try: + self.calibration.set_probe_param(ans) + except AttributeError: + warn(f"Couldn't store the probe parameters in metadata as no calibration was found for this Probe instance, {self}") + pass + if returncalc: + return ans + + + + + + + + + # Kernel generation methods + + def get_kernel( + self, + mode = 'flat', + origin = None, + data = None, + returncalc = True, + **kwargs + ): + """ + Creates a cross-correlation kernel from the vacuum probe. + + Specific behavior and valid keyword arguments depend on the `mode` + specified. In each case, the center of the probe is shifted to the + origin and the kernel normalized such that it sums to 1. This is the + only processing performed if mode is 'flat'. Otherwise, a centrosymmetric + region of negative intensity is added around the probe intended to promote + edge-filtering-like behavior during cross correlation, with the + functional form of the subtracted region defined by `mode` and the + relevant **kwargs. For normalization, flat probes integrate to 1, and the + remaining probes integrate to 1 before subtraction and 0 after. Required + keyword arguments are: + + - 'flat': No required arguments. This mode is recommended for bullseye + or other structured probes + - 'gaussian': Required arg `sigma` (number), the width (standard + deviation) of a centered gaussian to be subtracted. + - 'sigmoid': Required arg `radii` (2-tuple), the inner and outer radii + (ri,ro) of an annular region with a sine-squared sigmoidal radial + profile to be subtracted. + - 'sigmoid_log': Required arg `radii` (2-tuple), the inner and outer radii + (ri,ro) of an annular region with a logistic sigmoidal radial + profile to be subtracted. + + Parameters + ---------- + mode : str + must be in 'flat','gaussian','sigmoid','sigmoid_log' + origin : 2-tuple, optional + specify the origin. If not passed, looks for a value for the probe + origin in metadata. If not found there, calls .measure_probe. + data : 2d array, optional + if specified, uses this array instead of the probe image to compute + the kernel + **kwargs + see descriptions above + + Returns + ------- + kernel : 2D array + """ + + modes = [ + 'flat', + 'gaussian', + 'sigmoid', + 'sigmoid_log' + ] + + # parse args + assert mode in modes, f"mode must be in {modes}. Received {mode}" + + # get function + function_dict = { + 'flat' : self.get_probe_kernel_flat, + 'gaussian' : self.get_probe_kernel_edge_gaussian, + 'sigmoid' : self._get_probe_kernel_edge_sigmoid_sine_squared, + 'sigmoid_log' : self._get_probe_kernel_edge_sigmoid_sine_squared + } + fn = function_dict[mode] + + # check for the origin + if origin is None: + try: + x = self.calibration.get_probe_params() + except AttributeError: + x = None + finally: + if x is None: + origin = None + else: + r,x,y = x + origin = (x,y) + + # get the data + probe = data if data is not None else self.probe + + print() + print('meow') + print(kwargs) + print() + + # compute + kern = fn( + probe, + origin = origin, + **kwargs + ) + + # add to the Probe + self.kernel = kern + + # return + if returncalc: + return kern + + + + @staticmethod + def get_probe_kernel_flat( + probe, + origin=None, + bilinear=False + ): + """ + Creates a cross-correlation kernel from the vacuum probe by normalizing + and shifting the center. + + Parameters + ---------- + probe : 2d array + the vacuum probe + origin : 2-tuple (optional) + the origin of diffraction space. If not specified, finds the origin + using get_probe_radius. + bilinear : bool (optional) + By default probe is shifted via a Fourier transform. Setting this to + True overrides it and uses bilinear shifting. Not recommended! + + Returns + ------- + kernel : ndarray + the cross-correlation kernel corresponding to the probe, in real + space + """ + Q_Nx, Q_Ny = probe.shape + + # Get CoM + if origin is None: + _,xCoM,yCoM = get_probe_size(probe) + else: + xCoM,yCoM = origin + + # Normalize + probe = self.probe/np.sum(probe) + + # Shift center to corners of array + probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) + + # Return + return probe_kernel + + + @staticmethod + def get_probe_kernel_edge_gaussian( + probe, + sigma, + origin=None, + bilinear=True, + ): + """ + Creates a cross-correlation kernel from the probe, subtracting a + gaussian from the normalized probe such that the kernel integrates to + zero, then shifting the center of the probe to the array corners. + + Parameters + ---------- + probe : ndarray + the diffraction pattern corresponding to the probe over vacuum + sigma : float + the width of the gaussian to subtract, relative to the standard + deviation of the probe + origin : 2-tuple (optional) + the origin of diffraction space. If not specified, finds the origin + using get_probe_radius. + bilinear : bool + By default probe is shifted via a Fourier transform. Setting this to + True overrides it and uses bilinear shifting. Not recommended! + + Returns + ------- + kernel : ndarray + the cross-correlation kernel + """ + Q_Nx, Q_Ny = probe.shape + + # Get CoM + if origin is None: + _,xCoM,yCoM = get_probe_size(probe) + else: + xCoM,yCoM = origin + + # Shift probe to origin + probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) + + # Generate normalization kernel + # Coordinates + qy,qx = np.meshgrid( + np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, + np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) + qr2 = (qx**2 + qy**2) + # Calculate Gaussian normalization kernel + qstd2 = np.sum(qr2*probe_kernel) / np.sum(probe_kernel) + kernel_norm = np.exp(-qr2 / (2*qstd2*sigma**2)) + + # Output normalized kernel + probe_kernel = probe_kernel/np.sum(probe_kernel) - kernel_norm/np.sum(kernel_norm) + + return probe_kernel + + + @staticmethod + def get_probe_kernel_edge_sigmoid( + probe, + radii, + origin=None, + type='sine_squared', + bilinear=True, + ): + """ + Creates a convolution kernel from an average probe, subtracting an annular + trench about the probe such that the kernel integrates to zero, then + shifting the center of the probe to the array corners. + + Parameters + ---------- + probe : ndarray + the diffraction pattern corresponding to the probe over vacuum + radii : 2-tuple + the sigmoid inner and outer radii + origin : 2-tuple (optional) + the origin of diffraction space. If not specified, finds the origin + using get_probe_radius. + type : string + must be 'logistic' or 'sine_squared' + bilinear : bool + By default probe is shifted via a Fourier transform. Setting this to + True overrides it and uses bilinear shifting. Not recommended! + + Returns + ------- + kernel : 2d array + the cross-correlation kernel + """ + valid_types = ('logistic','sine_squared') + assert(type in valid_types), "type must be in {}".format(valid_types) + Q_Nx, Q_Ny = probe.shape + ri,ro = radii + + # Get CoM + if origin is None: + _,xCoM,yCoM = get_probe_size(probe) + else: + xCoM,yCoM = origin + + # Shift probe to origin + probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) + + # Generate normalization kernel + # Coordinates + qy,qx = np.meshgrid( + np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, + np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) + qr = np.sqrt(qx**2 + qy**2) + # Calculate sigmoid + if type == 'logistic': + r0 = 0.5*(ro+ri) + sigma = 0.25*(ro-ri) + sigmoid = 1/(1+np.exp((qr-r0)/sigma)) + elif type == 'sine_squared': + sigmoid = (qr - ri) / (ro - ri) + sigmoid = np.minimum(np.maximum(sigmoid, 0.0), 1.0) + sigmoid = np.cos((np.pi/2)*sigmoid)**2 + else: + raise Exception("type must be in {}".format(valid_types)) + + # Output normalized kernel + probe_kernel = probe_kernel/np.sum(probe_kernel) - sigmoid/np.sum(sigmoid) + + return probe_kernel + + + def _get_probe_kernel_edge_sigmoid_sine_squared( + self, + probe, + radii, + origin=None, + **kwargs, + ): + return self.get_probe_kernel_edge_sigmoid( + probe, + radii, + origin = origin, + type='sine_squared', + **kwargs, + ) + + def _get_probe_kernel_edge_sigmoid_logistic( + self, + probe, + radii, + origin=None, + **kwargs, + ): + return self.get_probe_kernel_edge_sigmoid( + probe, + radii, + origin = origin, + type='logistic', + **kwargs + ) + + + + + + + + + diff --git a/py4DSTEM/process/probe/probe.py b/py4DSTEM/process/diskdetection/probe_gen_methods.py similarity index 69% rename from py4DSTEM/process/probe/probe.py rename to py4DSTEM/process/diskdetection/probe_gen_methods.py index 04a2926de..2e5925f24 100644 --- a/py4DSTEM/process/probe/probe.py +++ b/py4DSTEM/process/diskdetection/probe_gen_methods.py @@ -258,125 +258,6 @@ def get_probe_from_4Dscan_ROI_mask( -def get_probe_from_vacuum_3Dstack( - data, - mask_threshold=0.2, - mask_expansion=12, - mask_opening=3 - ): - """ - Averages all diffraction patterns in a 3D stack of diffraction patterns, - assumed to be taken over vacuum, to create and average vacuum probe. No - alignment is performed - i.e. it is assumed that the beam was stationary - during acquisition of the stack. - - Values outisde the average probe are zeroed, using a binary mask determined - by the optional parameters mask_threshold, mask_expansion, and mask_opening. - An initial binary mask is created using a threshold of less than - mask_threshold times the maximal probe value. A morphological opening of - mask_opening pixels is performed to eliminate stray pixels (e.g. from - x-rays), followed by a dilation of mask_expansion pixels to ensure the - entire probe is captured. - - Args: - data (array): a 3D stack of vacuum diffraction patterns, shape - (Q_Nx,Q_Ny,N) - mask_threshold (float): threshold determining mask which zeros values - outside of probe - mask_expansion (int): number of pixels by which the zeroing mask is - expanded to capture the full probe - mask_opening (int): size of binary opening used to eliminate stray - bright pixels - - Returns: - (array of shape (Q_Nx,Q_Ny)): the average probe - """ - probe = np.average(data,axis=2) - - mask = probe > np.max(probe)*mask_threshold - mask = binary_opening(mask, iterations=mask_opening) - mask = binary_dilation(mask, iterations=1) - mask = np.cos((np.pi/2)*np.minimum(distance_transform_edt(np.logical_not(mask)) / mask_expansion, 1))**2 - - return probe*mask - - - - -def get_probe_from_vacuum_2Dimage( - data, - mask_threshold=0.2, - mask_expansion=12, - mask_opening=3 - ): - """ - A single image of the probe over vacuum is processed by zeroing values - outside the central disk, using a binary mask determined by the optional - parameters mask_threshold, mask_expansion, and mask_opening. An initial - binary mask is created using a threshold of less than mask_threshold time - the maximal probe value. A morphological opening of mask_opening pixels is - performed to eliminate stray pixels (e.g. from x-rays), followed by a - dilation of mask_expansion pixels to ensure the entire probe is captured. - - Args: - data (array): a 2D array of the vacuum diffraction pattern, shape - (Q_Nx,Q_Ny) - mask_threshold (float): threshold determining mask which zeros values - outside of probe - mask_expansion (int): number of pixels by which the zeroing mask is - expanded to capture the full probe - mask_opening (int): size of binary opening used to eliminate stray - bright pixels - - Returns: - (array of shape (Q_Nx,Q_Ny)) the average probe - """ - mask = data > np.max(data)*mask_threshold - mask = binary_opening(mask, iterations=mask_opening) - mask = binary_dilation(mask, iterations=1) - mask = np.cos((np.pi/2)*np.minimum(distance_transform_edt(np.logical_not(mask)) / mask_expansion, 1))**2 - - return data*mask - - - - -def get_probe_synthetic( - radius, - width, - Qshape - ): - """ - Makes a synthetic probe, with the functional form of a disk blurred by a - sigmoid (a logistic function). - - Args: - radius (float): the probe radius - width (float): the blurring of the probe edge. width represents the - full width of the blur, with x=-w/2 to x=+w/2 about the edge - spanning values of ~0.12 to 0.88 - Qshape (2 tuple): the diffraction plane dimensions - - Returns: - (ndarray of shape (Q_Nx,Q_Ny)): the probe - """ - # Make coords - Q_Nx,Q_Ny = Qshape - qy,qx = np.meshgrid(np.arange(Q_Ny),np.arange(Q_Nx)) - qy,qx = qy - Q_Ny/2., qx-Q_Nx/2. - qr = np.sqrt(qx**2+qy**2) - - # Shift zero to disk edge - qr = qr - radius - - # Calculate logistic function - probe = 1/(1+np.exp(4*qr/width)) - - return probe - - - - diff --git a/py4DSTEM/process/probe/__init__.py b/py4DSTEM/process/probe/__init__.py deleted file mode 100644 index a77a14ae6..000000000 --- a/py4DSTEM/process/probe/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from py4DSTEM.process.probe.probe import * -from py4DSTEM.process.probe.kernel import * - diff --git a/py4DSTEM/process/probe/kernel.py b/py4DSTEM/process/probe/kernel.py deleted file mode 100644 index f415ae96d..000000000 --- a/py4DSTEM/process/probe/kernel.py +++ /dev/null @@ -1,279 +0,0 @@ -# Functions for preparing the probe for cross-correlative template matching. - - -import numpy as np - -from py4DSTEM.process.utils import get_shifted_ar -from py4DSTEM.process.calibration import get_probe_size - - -def get_kernel( - probe, - mode = 'flat', - **kwargs - ): - """ - Creates a kernel from the probe for cross-correlative template matching. - - Precise behavior and valid keyword arguments depend on the `mode` - selected. In each case, the center of the probe is shifted to the - origin and the kernel normalized such that it sums to 1. In 'flat' - mode, this is the only processing performed. In the remaining modes, - some additional processing is performed which adds a ring of - negative intensity around the central probe, which results in - edge-filetering-like behavior during cross correlation. Valid modes - are: - - - 'flat': creates a flat probe kernel. For bullseye or other - structured probes, this mode is recommended. - - 'gaussian': subtracts a gaussian with a width of standard - deviation 'sigma' - - 'sigmoid': subtracts an annulus with inner and outer radii - of (ri,ro) and a sine-squared sigmoid radial profile from - the probe template. - - 'sigmoid_log': subtracts an annulus with inner and outer radii - of (ri,ro) and a logistic sigmoid radial profile from - the probe template. - - Each mode accepts 'center' (2-tuple) as a kwarg to manually specify - the center of the probe, which is otherwise autodetected. Modes which - accept additional kwargs and those arguments are: - - - 'gaussian': - sigma (number) - - 'sigmoid': - radii (2-tuple) - - 'sigmoid_log': - radii (2-tuple) - - Accepts: - probe (2D array): - mode (str): must be in 'flat','gaussian','sigmoid','sigmoid_log' - **kwargs: depend on `mode`, see above - - Returns: - (2D array) - """ - - modes = [ - 'flat', - 'gaussian', - 'sigmoid', - 'sigmoid_log' - ] - - # parse args - assert mode in modes, f"mode must be in {modes}. Received {mode}" - - # get function - fn_dict = _make_function_dict() - fn = fn_dict[mode] - - # compute and return - kernel = fn(probe, **kwargs) - return kernel - - - -def _make_function_dict(): - d = { - 'flat' : get_probe_kernel, - 'gaussian' : get_probe_kernel_edge_gaussian, - 'sigmoid' : _get_probe_kernel_edge_sigmoid_sine_squared, - 'sigmoid_log' : _get_probe_kernel_edge_sigmoid_sine_squared - } - return d - - - - - -def get_probe_kernel( - probe, - origin=None, - bilinear=True - ): - """ - Creates a convolution kernel from an average probe, by normalizing, then - shifting the center of the probe to the corners of the array. - - Args: - probe (ndarray): the diffraction pattern corresponding to the probe over - vacuum - origin (2-tuple or None): if None (default), finds the origin using - get_probe_radius. Otherwise, should be a 2-tuple (x0,y0) specifying - the origin position - bilinear (bool): By default probe is shifted via a Fourier transform. - Setting this to True overrides it and uses bilinear shifting. - Not recommended! - - Returns: - (ndarray): the convolution kernel corresponding to the probe, in real - space - """ - Q_Nx, Q_Ny = probe.shape - - # Get CoM - if origin is None: - _,xCoM,yCoM = get_probe_size(probe) - else: - xCoM,yCoM = origin - - # Normalize - probe = probe/np.sum(probe) - - # Shift center to corners of array - probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) - - return probe_kernel - - -def get_probe_kernel_edge_gaussian( - probe, - sigma, - origin=None, - bilinear=True, - ): - """ - Creates a convolution kernel from an average probe, subtracting a gaussian - from the normalized probe such that the kernel integrates to zero, then - shifting the center of the probe to the array corners. - - Args: - probe (ndarray): the diffraction pattern corresponding to the probe - over vacuum - sigma (float): the width of the gaussian to subtract, relative to - the standard deviation of the probe - origin (2-tuple or None): if None (default), finds the origin using - get_probe_radius. Otherwise, should be a 2-tuple (x0,y0) specifying - the origin position - bilinear (bool): By default probe is shifted via a Fourier transform. - Setting this to True overrides it and uses bilinear shifting. - Not recommended! - - Returns: - (ndarray) the convolution kernel corresponding to the probe - """ - Q_Nx, Q_Ny = probe.shape - - # Get CoM - if origin is None: - _,xCoM,yCoM = get_probe_size(probe) - else: - xCoM,yCoM = origin - - # Shift probe to origin - probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) - - # Generate normalization kernel - # Coordinates - qy,qx = np.meshgrid( - np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, - np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) - qr2 = (qx**2 + qy**2) - # Calculate Gaussian normalization kernel - qstd2 = np.sum(qr2*probe_kernel) / np.sum(probe_kernel) - kernel_norm = np.exp(-qr2 / (2*qstd2*sigma**2)) - - # Output normalized kernel - probe_kernel = probe_kernel/np.sum(probe_kernel) - kernel_norm/np.sum(kernel_norm) - - return probe_kernel - - -def get_probe_kernel_edge_sigmoid( - probe, - radii, - origin=None, - type='sine_squared', - bilinear=True, - ): - """ - Creates a convolution kernel from an average probe, subtracting an annular - trench about the probe such that the kernel integrates to zero, then - shifting the center of the probe to the array corners. - - Args: - probe (ndarray): the diffraction pattern corresponding to the probe over - vacuum - radii (2-tuple): the sigmoid inner and outer radii, from the probe center - origin (2-tuple or None): if None (default), finds the origin using - get_probe_radius. Otherwise, should be a 2-tuple (x0,y0) specifying - the origin position - type (string): must be 'logistic' or 'sine_squared' - bilinear (bool): By default probe is shifted via a Fourier transform. - Setting this to True overrides it and uses bilinear shifting. - Not recommended! - - Returns: - (ndarray): the convolution kernel corresponding to the probe - """ - valid_types = ('logistic','sine_squared') - assert(type in valid_types), "type must be in {}".format(valid_types) - Q_Nx, Q_Ny = probe.shape - ri,ro = radii - - # Get CoM - if origin is None: - _,xCoM,yCoM = get_probe_size(probe) - else: - xCoM,yCoM = origin - - # Shift probe to origin - probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) - - # Generate normalization kernel - # Coordinates - qy,qx = np.meshgrid( - np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, - np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) - qr = np.sqrt(qx**2 + qy**2) - # Calculate sigmoid - if type == 'logistic': - r0 = 0.5*(ro+ri) - sigma = 0.25*(ro-ri) - sigmoid = 1/(1+np.exp((qr-r0)/sigma)) - elif type == 'sine_squared': - sigmoid = (qr - ri) / (ro - ri) - sigmoid = np.minimum(np.maximum(sigmoid, 0.0), 1.0) - sigmoid = np.cos((np.pi/2)*sigmoid)**2 - else: - raise Exception("type must be in {}".format(valid_types)) - - # Output normalized kernel - probe_kernel = probe_kernel/np.sum(probe_kernel) - sigmoid/np.sum(sigmoid) - - return probe_kernel - - - -def _get_probe_kernel_edge_sigmoid_sine_squared( - probe, - radii, - origin=None, - **kwargs, - ): - return get_probe_kernel_edge_sigmoid( - probe, - radii, - origin = origin, - type='sine_squared', - **kwargs, - ) - -def _get_probe_kernel_edge_sigmoid_logistic( - probe, - radii, - origin=None, - **kwargs, - ): - return get_probe_kernel_edge_sigmoid( - probe, - radii, - origin = origin, - type='logistic', - **kwargs - ) - - - diff --git a/test/test_braggvectors.py b/test/test_braggvectors.py index e8a8d5ccc..107cf7a64 100644 --- a/test/test_braggvectors.py +++ b/test/test_braggvectors.py @@ -24,7 +24,7 @@ def setup_class(cls): mask = np.zeros(datacube.Rshape,dtype=bool) mask[28:33,14:19] = 1 probe = datacube.get_vacuum_probe( ROI=mask ) - alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.probe.get_probe_size( probe.probe ) + alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.calibration.get_probe_size( probe.probe ) probe.get_kernel( mode='sigmoid', origin=(qx0_pr,qy0_pr), diff --git a/test/test_native_io/test_single_object_io.py b/test/test_native_io/test_single_object_io.py index ae77b01cd..6687274c5 100644 --- a/test/test_native_io/test_single_object_io.py +++ b/test/test_native_io/test_single_object_io.py @@ -14,8 +14,8 @@ RealSlice, QPoints, ) -from py4DSTEM.process.diskdetection import BraggVectors -from py4DSTEM.classes import Probe, VirtualDiffraction, VirtualImage +from py4DSTEM.process.diskdetection import BraggVectors,Probe +from py4DSTEM.classes import VirtualDiffraction, VirtualImage # Set paths dirpath = py4DSTEM._TESTPATH diff --git a/test/test_probe.py b/test/test_probe.py new file mode 100644 index 000000000..ad10c3100 --- /dev/null +++ b/test/test_probe.py @@ -0,0 +1,65 @@ +import py4DSTEM +from py4DSTEM import Probe +import numpy as np +from os.path import join + +# set filepath +path = py4DSTEM._TESTPATH + "/small_datacube.dm4" + + + +class TestProbe: + + # setup/teardown + def setup_class(cls): + + # Read datacube + datacube = py4DSTEM.import_file(path) + cls.datacube = datacube + + # tests + + def test_probe_gen_from_dp(self): + p = Probe.from_vacuum_data( + self.datacube[0,0] + ) + assert(isinstance(p,Probe)) + pass + + def test_probe_gen_from_stack(self): + # get a 3D stack + x,y = np.zeros(10).astype(int),np.arange(10).astype(int) + data = self.datacube.data[x,y,:,:] + # get the probe + p = Probe.from_vacuum_data( + data + ) + assert(isinstance(p,Probe)) + pass + + def test_probe_gen_from_datacube_ROI_1(self): + ROI = np.zeros(self.datacube.Rshape,dtype=bool) + ROI[3:7,5:10] = True + p = self.datacube.get_vacuum_probe( ROI ) + assert(isinstance(p,Probe)) + + self.datacube.tree() + self.datacube.tree(True) + _p = self.datacube.tree('probe') + print(_p) + + assert(p is self.datacube.tree('probe')) + pass + + def test_probe_gen_from_datacube_ROI_2(self): + ROI = (3,7,5,10) + p = self.datacube.get_vacuum_probe( ROI ) + assert(isinstance(p,Probe)) + assert(p is self.datacube.tree('probe')) + pass + + + + + + diff --git a/test/test_workflow/test_disk_detection_basic.py b/test/test_workflow/test_disk_detection_basic.py index 058fb67ee..60a5e2aa1 100644 --- a/test/test_workflow/test_disk_detection_basic.py +++ b/test/test_workflow/test_disk_detection_basic.py @@ -23,7 +23,7 @@ def setup_class(cls): mask = zeros(datacube.Rshape,dtype=bool) mask[28:33,14:19] = 1 probe = datacube.get_vacuum_probe( ROI=mask ) - alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.probe.get_probe_size( probe.probe ) + alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.calibration.get_probe_size( probe.probe ) probe.get_kernel( mode='sigmoid', origin=(qx0_pr,qy0_pr), diff --git a/test/test_workflow/test_disk_detection_with_calibration.py b/test/test_workflow/test_disk_detection_with_calibration.py index c1bb4a581..b93e2d00b 100644 --- a/test/test_workflow/test_disk_detection_with_calibration.py +++ b/test/test_workflow/test_disk_detection_with_calibration.py @@ -23,7 +23,7 @@ def setup_class(cls): mask = zeros(datacube.Rshape,dtype=bool) mask[28:33,14:19] = 1 probe = datacube.get_vacuum_probe( ROI=mask ) - alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.probe.get_probe_size( probe.probe ) + alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.calibration.get_probe_size( probe.probe ) probe.get_kernel( mode='sigmoid', origin=(qx0_pr,qy0_pr), From cc57170407ca0118042d16aa4477f0f6fda14825 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Wed, 28 Jun 2023 17:16:55 -0700 Subject: [PATCH 079/362] Adding 2D calibrations --- py4DSTEM/io/filereaders/read_abTEM.py | 14 ++++++++++++-- py4DSTEM/io/filereaders/read_arina.py | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index af0c71c63..cf6892d76 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -60,9 +60,19 @@ def read_abTEM( elif len(data.shape) == 2: if units[0] == b"mrad": diffraction = VirtualDiffraction(data=data) - # TODO, calibrations for 2D + if sampling[0] != sampling[1]: + print( + "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with x calibration" + ) + diffraction.calibration.set_Q_pixel_units(units[0].decode("utf-8")) + diffraction.calibration.set_Q_pixel_size(sampling[0]) return diffraction elif units[0] == b"\xc3\x85": image = VirtualImage(data=data) - # TODO calibrations for 2D + if sampling[0] != sampling[1]: + print( + "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" + ) + image.calibration.set_Q_pixel_units("A") + image.calibration.set_Q_pixel_size(sampling[0]) return image diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 0f334f52b..1434301fe 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -7,7 +7,7 @@ def read_arina( filename, - scan_width, + scan_width=1, mem="RAM", binfactor: int = 1, dtype_bin: float = None, From 439afedf1a9120110346ba42c84eaefc0a647e0d Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 28 Jun 2023 22:10:03 -0400 Subject: [PATCH 080/362] correctly links + sets cals/data on read --- py4DSTEM/data/calibration.py | 9 +- py4DSTEM/io/read.py | 18 ++-- py4DSTEM/io/sample_file_ids.py | 1 - py4DSTEM/io/save.py | 36 +++++++- py4DSTEM/process/calibration/origin.py | 86 +++++++++---------- py4DSTEM/process/calibration/probe.py | 7 ++ .../diskdetection/braggvector_methods.py | 21 +++-- .../process/diskdetection/braggvectors.py | 6 ++ py4DSTEM/process/diskdetection/probe.py | 11 ++- 9 files changed, 128 insertions(+), 67 deletions(-) delete mode 100644 py4DSTEM/io/sample_file_ids.py diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index e2fe0c393..6077864f3 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -202,10 +202,10 @@ def __init__( self._targets = [] # set initial pixel values - self.set_Q_pixel_size(1) - self.set_R_pixel_size(1) - self.set_Q_pixel_units('pixels') - self.set_R_pixel_units('pixels') + self['Q_pixel_size'] = 1 + self['R_pixel_size'] = 1 + self['Q_pixel_units'] = 'pixels' + self['R_pixel_units'] = 'pixels' # EMD root property @@ -779,6 +779,7 @@ def to_h5(self,group): self['_target_paths'] = targets # Save the metadata Metadata.to_h5(self,group) + del(self._params['_target_paths']) # read @classmethod diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 589486040..79291fe86 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -82,13 +82,15 @@ def read( version = emd._get_EMD_version(filepath) if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" + # read data = emd.read( filepath, emdpath = datapath, tree = tree ) - # calibration links + + # add calibration links if isinstance(data,py4DSTEM.Data): with warnings.catch_warnings(): warnings.simplefilter('ignore') @@ -102,16 +104,22 @@ def read( cal = None if cal is not None: try: + root_treepath = cal['_root_treepath'] target_paths = cal['_target_paths'] del(cal._params['_target_paths']) for p in target_paths: - d = data.root.tree(p) - cal.register_target( d ) - if hasattr(d,'setcal'): - d.setcal() + try: + p = p.replace(root_treepath,'') + d = data.root.tree(p) + cal.register_target( d ) + if hasattr(d,'setcal'): + d.setcal() + except AssertionError: + pass except KeyError: pass cal.calibrate() + # return if verbose: print("Done.") return data diff --git a/py4DSTEM/io/sample_file_ids.py b/py4DSTEM/io/sample_file_ids.py deleted file mode 100644 index 8b1378917..000000000 --- a/py4DSTEM/io/sample_file_ids.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/py4DSTEM/io/save.py b/py4DSTEM/io/save.py index 3d2ae95d8..ce79b6cd0 100644 --- a/py4DSTEM/io/save.py +++ b/py4DSTEM/io/save.py @@ -1,4 +1,38 @@ -from emdfile import save +from emdfile import save as _save + + +def save( + filepath, + data, + mode='w', + emdpath=None, + tree=True + ): + """ + Saves data to an EMD 1.0 formatted HDF5 file at filepath. + + For the full docstring, see py4DSTEM.emdfile.save. + """ + # This function wraps emdfile's save and adds a small piece + # of metadata to the calibration to allow linking to calibrated + # data items on read + + cal = None + if hasattr(data,'calibration') and data.calibration is not None: + cal = data.calibration + rp = '/'.join(data._treepath.split('/')[:-1]) + cal['_root_treepath'] = rp + + _save( + filepath, + data = data, + mode = mode, + emdpath = emdpath, + tree = tree + ) + + if cal is not None: + del(cal._params['_root_treepath']) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 5a4b09803..b3a141231 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -12,49 +12,49 @@ from py4DSTEM.process.utils import get_CoM, add_to_2D_array_from_floats, get_maxima_2D - -# origin setting decorators - -def set_measured_origin(fun): - """ - This is intended as a decorator function to wrap other functions which measure - the position of the origin. If some function `get_the_origin` returns the - position of the origin as a tuple of two (R_Nx,R_Ny)-shaped arrays, then - decorating the function definition like - - >>> @measure_origin - >>> def get_the_origin(...): - - will make the function also save those arrays as the measured origin in the - calibration associated with the data used for the measurement. Any existing - measured origin value will be overwritten. - - For the wrapper to work, the decorated function's first argument must have - a .calibration property, and its first two return values must be qx0,qy0. - """ - @functools.wraps(fun) - def wrapper(*args,**kwargs): - ans = fun(*args,**kwargs) - data = args[0] - cali = data.calibration - cali.set_origin_meas((ans[0],ans[1])) - return ans - return wrapper - - -def set_fit_origin(fun): - """ - See docstring for `set_measured_origin` - """ - @functools.wraps(fun) - def wrapper(*args,**kwargs): - ans = fun(*args,**kwargs) - data = args[0] - cali = data.calibration - cali.set_origin((ans[0],ans[1])) - return ans - return wrapper - +# +# # origin setting decorators +# +# def set_measured_origin(fun): +# """ +# This is intended as a decorator function to wrap other functions which measure +# the position of the origin. If some function `get_the_origin` returns the +# position of the origin as a tuple of two (R_Nx,R_Ny)-shaped arrays, then +# decorating the function definition like +# +# >>> @measure_origin +# >>> def get_the_origin(...): +# +# will make the function also save those arrays as the measured origin in the +# calibration associated with the data used for the measurement. Any existing +# measured origin value will be overwritten. +# +# For the wrapper to work, the decorated function's first argument must have +# a .calibration property, and its first two return values must be qx0,qy0. +# """ +# @functools.wraps(fun) +# def wrapper(*args,**kwargs): +# ans = fun(*args,**kwargs) +# data = args[0] +# cali = data.calibration +# cali.set_origin_meas((ans[0],ans[1])) +# return ans +# return wrapper +# +# +# def set_fit_origin(fun): +# """ +# See docstring for `set_measured_origin` +# """ +# @functools.wraps(fun) +# def wrapper(*args,**kwargs): +# ans = fun(*args,**kwargs) +# data = args[0] +# cali = data.calibration +# cali.set_origin((ans[0],ans[1])) +# return ans +# return wrapper +# diff --git a/py4DSTEM/process/calibration/probe.py b/py4DSTEM/process/calibration/probe.py index d77f88500..8d9a87ae2 100644 --- a/py4DSTEM/process/calibration/probe.py +++ b/py4DSTEM/process/calibration/probe.py @@ -34,11 +34,18 @@ def get_probe_size(DP, thresh_lower=0.01, thresh_upper=0.99, N=100): * **x0**: *(float)* the x position of the central disk center * **y0**: *(float)* the y position of the central disk center """ + from py4DSTEM.process.diskdetection import Probe + + # parse input + if isinstance(DP,Probe): + DP = DP.probe + thresh_vals = np.linspace(thresh_lower, thresh_upper, N) r_vals = np.zeros(N) # Get r for each mask DPmax = np.max(DP) + print(DPmax) for i in range(len(thresh_vals)): thresh = thresh_vals[i] mask = DP > DPmax * thresh diff --git a/py4DSTEM/process/diskdetection/braggvector_methods.py b/py4DSTEM/process/diskdetection/braggvector_methods.py index bb03852ed..d55332214 100644 --- a/py4DSTEM/process/diskdetection/braggvector_methods.py +++ b/py4DSTEM/process/diskdetection/braggvector_methods.py @@ -4,7 +4,6 @@ from scipy.ndimage import gaussian_filter from emdfile import Array,Metadata from emdfile import _read_metadata -from py4DSTEM.process.calibration.origin import set_measured_origin, set_fit_origin from py4DSTEM.process.utils import get_CoM @@ -179,7 +178,6 @@ def histogram( # calibration measurements - @set_measured_origin def measure_origin( self, center_guess = None, @@ -269,11 +267,14 @@ def measure_origin( qx0[Rx, Ry] = x0 qy0[Rx, Ry] = y0 + # set calibration metadata + self.calibration.set_origin_meas((qx0,qy0)) + self.calibration.set_origin_meas_mask(mask) + # return return qx0, qy0, mask - @set_measured_origin def measure_origin_beamstop( self, center_guess, @@ -353,14 +354,18 @@ def measure_origin_beamstop( y0_curr = np.mean(centers[found_center,1]) center_curr = x0_curr,y0_curr - # return + # collect answers mask = found_center qx0,qy0 = centers[:,:,0],centers[:,:,1] + # set calibration metadata + self.calibration.set_origin_meas((qx0,qy0)) + self.calibration.set_origin_meas_mask(mask) + + # return return qx0,qy0,mask - @set_fit_origin def fit_origin( self, mask=None, @@ -456,6 +461,8 @@ def fit_origin( **kwargs, ) + # update calibration metadata + self.calibration.set_origin((qx0_fit,qy0_fit)) self.setcal() if returncalc: @@ -472,11 +479,11 @@ def fit_p_ellipse( ): """ Args: - bvm (BraggVectorMap): a 2D array used for ellipse fitting + bvm (BraggVectorMap): a 2D array used for ellipse fitting center (2-tuple of floats): the center (x0,y0) of the annular fitting region fitradii (2-tuple of floats): inner and outer radii (ri,ro) of the fit region mask (ar-shaped ndarray of bools): ignore data wherever mask==True - + Returns: p_ellipse if returncal is True """ diff --git a/py4DSTEM/process/diskdetection/braggvectors.py b/py4DSTEM/process/diskdetection/braggvectors.py index 15b326475..e6566a33e 100644 --- a/py4DSTEM/process/diskdetection/braggvectors.py +++ b/py4DSTEM/process/diskdetection/braggvectors.py @@ -80,9 +80,15 @@ def __init__( "pixel" : False, "rotate" : False, } + + # register with calibrations + self.calibration.register_target(self) + + # setup vector getters self._set_raw_vector_getter() self._set_cal_vector_getter() + @property def calstate(self): return self._calstate diff --git a/py4DSTEM/process/diskdetection/probe.py b/py4DSTEM/process/diskdetection/probe.py index 4952044fa..3525e42be 100644 --- a/py4DSTEM/process/diskdetection/probe.py +++ b/py4DSTEM/process/diskdetection/probe.py @@ -326,7 +326,7 @@ def get_kernel( must be in 'flat','gaussian','sigmoid','sigmoid_log' origin : 2-tuple, optional specify the origin. If not passed, looks for a value for the probe - origin in metadata. If not found there, calls .measure_probe. + origin in metadata. If not found there, calls .measure_disk. data : 2d array, optional if specified, uses this array instead of the probe image to compute the kernel @@ -373,11 +373,6 @@ def get_kernel( # get the data probe = data if data is not None else self.probe - print() - print('meow') - print(kwargs) - print() - # compute kern = fn( probe, @@ -530,6 +525,10 @@ def get_probe_kernel_edge_sigmoid( kernel : 2d array the cross-correlation kernel """ + # parse inputs + if isinstance(probe,Probe): + probe = probe.probe + valid_types = ('logistic','sine_squared') assert(type in valid_types), "type must be in {}".format(valid_types) Q_Nx, Q_Ny = probe.shape From 0392cb0146af52eb58d32b3657c53f592ad5772c Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 28 Jun 2023 22:39:20 -0400 Subject: [PATCH 081/362] fix extraneous save warning --- py4DSTEM/io/save.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/io/save.py b/py4DSTEM/io/save.py index ce79b6cd0..ce0076724 100644 --- a/py4DSTEM/io/save.py +++ b/py4DSTEM/io/save.py @@ -1,5 +1,5 @@ from emdfile import save as _save - +import warnings def save( filepath, @@ -18,10 +18,12 @@ def save( # data items on read cal = None - if hasattr(data,'calibration') and data.calibration is not None: - cal = data.calibration - rp = '/'.join(data._treepath.split('/')[:-1]) - cal['_root_treepath'] = rp + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + if hasattr(data,'calibration') and data.calibration is not None: + cal = data.calibration + rp = '/'.join(data._treepath.split('/')[:-1]) + cal['_root_treepath'] = rp _save( filepath, From 4e057a9aa7a728d75447a8b826d12f35c7aedbc7 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 29 Jun 2023 00:11:56 -0400 Subject: [PATCH 082/362] legacy13 stackarray bugfix --- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 9bafe15d2..c9509d9f3 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -1,5 +1,6 @@ # Convert v13 to v14 classes +import numpy as np from emdfile import tqdmnd @@ -138,9 +139,13 @@ def _v13_to_14_cls(obj): ) elif isinstance(obj, DiffractionSlice13): + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data x = DiffractionSlice( name = obj.name, - data = obj.data, + data = data, units = obj.units, slicelabels = obj.slicelabels ) @@ -152,9 +157,13 @@ def _v13_to_14_cls(obj): ) elif isinstance(obj, RealSlice13): + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data x = RealSlice( name = obj.name, - data = obj.data, + data = data, units = obj.units, slicelabels = obj.slicelabels ) @@ -196,9 +205,13 @@ def _v13_to_14_cls(obj): elif isinstance(obj, Array13): # prepare arguments + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data args = { 'name' : obj.name, - 'data' : obj.data + 'data' : data } if hasattr(obj,'units'): args['units'] = obj.units if hasattr(obj,'dim_names'): args['dim_names'] = obj.dim_names From 067d42172ba1cea78c7aea60c0bb7c240c36e78d Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 29 Jun 2023 00:18:52 -0400 Subject: [PATCH 083/362] legacy io bugfix --- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 1b0deafaa..a569b8915 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -1,5 +1,6 @@ # Convert v13 to v14 classes +import numpy as np from emdfile import tqdmnd @@ -137,9 +138,13 @@ def _v13_to_14_cls(obj): ) elif isinstance(obj, DiffractionSlice13): + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data x = DiffractionSlice( name = obj.name, - data = obj.data, + data = data, units = obj.units, slicelabels = obj.slicelabels ) @@ -151,9 +156,13 @@ def _v13_to_14_cls(obj): ) elif isinstance(obj, RealSlice13): + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data x = RealSlice( name = obj.name, - data = obj.data, + data = data, units = obj.units, slicelabels = obj.slicelabels ) @@ -195,9 +204,13 @@ def _v13_to_14_cls(obj): elif isinstance(obj, Array13): # prepare arguments + if obj.is_stack: + data = np.rollaxis(obj.data, axis=2) + else: + data = obj.data args = { 'name' : obj.name, - 'data' : obj.data + 'data' : data } if hasattr(obj,'units'): args['units'] = obj.units if hasattr(obj,'dim_names'): args['dim_names'] = obj.dim_names From 88047814216a615aa0fbec8777fe7022df50dba0 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 29 Jun 2023 06:58:30 -0700 Subject: [PATCH 084/362] remove print statement --- py4DSTEM/io/legacy/read_legacy_13.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/io/legacy/read_legacy_13.py b/py4DSTEM/io/legacy/read_legacy_13.py index ebf86d5c3..a8b2151ed 100644 --- a/py4DSTEM/io/legacy/read_legacy_13.py +++ b/py4DSTEM/io/legacy/read_legacy_13.py @@ -257,7 +257,6 @@ def _get_v13_class(grp): 'QPoints' : QPoints, 'BraggVectors' : BraggVectors } - print(grp) if 'py4dstem_class' in grp.attrs: classname = grp.attrs['py4dstem_class'] elif 'emd_group_type' in grp.attrs: From f4fad7aa0f3444ba15df0b206082a71aac4e2801 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 29 Jun 2023 12:46:49 -0400 Subject: [PATCH 085/362] patch emdfile RootedNode bug --- py4DSTEM/version.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/version.py b/py4DSTEM/version.py index 7be84a82a..4009e43c9 100644 --- a/py4DSTEM/version.py +++ b/py4DSTEM/version.py @@ -1,2 +1,2 @@ -__version__='0.14.1' +__version__='0.14.2' diff --git a/setup.py b/setup.py index 2f1e15a63..cdb55e891 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ 'gdown >= 4.4.0', 'dask >= 2.3.0', 'distributed >= 2.3.0', - 'emdfile >= 0.0.9', + 'emdfile == 0.0.8', ], extras_require={ 'ipyparallel': ['ipyparallel >= 6.2.4', 'dill >= 0.3.3'], From fb9a4191b8a5988f5619f668b8b47c3a1ec741c2 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 29 Jun 2023 12:47:58 -0400 Subject: [PATCH 086/362] patch emdfile bug --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2f1e15a63..cdb55e891 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ 'gdown >= 4.4.0', 'dask >= 2.3.0', 'distributed >= 2.3.0', - 'emdfile >= 0.0.9', + 'emdfile == 0.0.8', ], extras_require={ 'ipyparallel': ['ipyparallel >= 6.2.4', 'dill >= 0.3.3'], From 3b9c36b18cad9eabd85bc137abac208a17e52452 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 29 Jun 2023 12:48:22 -0400 Subject: [PATCH 087/362] patch emdfile bug --- py4DSTEM/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/version.py b/py4DSTEM/version.py index 7be84a82a..4009e43c9 100644 --- a/py4DSTEM/version.py +++ b/py4DSTEM/version.py @@ -1,2 +1,2 @@ -__version__='0.14.1' +__version__='0.14.2' From 31d7ce67ff25d24aa58ef99ba01597f08b1d1998 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 29 Jun 2023 13:29:20 -0700 Subject: [PATCH 088/362] probe imports --- py4DSTEM/process/diskdetection/__init__.py | 3 ++- py4DSTEM/process/diskdetection/probe_gen_methods.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/diskdetection/__init__.py b/py4DSTEM/process/diskdetection/__init__.py index 9d42a2ad5..6ea191fbd 100644 --- a/py4DSTEM/process/diskdetection/__init__.py +++ b/py4DSTEM/process/diskdetection/__init__.py @@ -2,7 +2,8 @@ from py4DSTEM.process.diskdetection.braggvectors import BraggVectors from py4DSTEM.process.diskdetection.braggvector_methods import BraggVectorMap from py4DSTEM.process.diskdetection.diskdetection import * - +from py4DSTEM.process.diskdetection.probe import * +from py4DSTEM.process.diskdetection.probe_gen_methods import * #from .diskdetection_aiml import * #from .diskdetection_parallel_new import * diff --git a/py4DSTEM/process/diskdetection/probe_gen_methods.py b/py4DSTEM/process/diskdetection/probe_gen_methods.py index 2e5925f24..8e7b1d717 100644 --- a/py4DSTEM/process/diskdetection/probe_gen_methods.py +++ b/py4DSTEM/process/diskdetection/probe_gen_methods.py @@ -6,7 +6,7 @@ from emdfile import tqdmnd from py4DSTEM.data import DataCube -from py4DSTEM.classes import Probe +from py4DSTEM.process.diskdetection import Probe from py4DSTEM.process.utils import get_shifted_ar, get_shift From edab61d7f7ea60bd8b5597c8ff61e046f6b3afb1 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Thu, 29 Jun 2023 17:26:11 -0400 Subject: [PATCH 089/362] fix bad merge? --- py4DSTEM/preprocess/preprocess.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 78394ce68..d809d68f5 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -645,8 +645,7 @@ def resample_data_diffraction( datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) - + if not resampling_factor: resampling_factor = old_size[2] / output_size[0] if datacube.calibration.get_Q_pixel_size() is not None: From 4c6fde6812f6b827edc0b6c450f8ba2997d38375 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Thu, 29 Jun 2023 17:35:17 -0400 Subject: [PATCH 090/362] add skopt to dependencies --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 2f1e15a63..a2bfbde83 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ 'matplotlib >= 3.2.2', 'scikit-image >= 0.17.2', 'scikit-learn >= 0.23.2', + 'scikit-optimize >= 0.9.0', 'tqdm >= 4.46.1', 'dill >= 0.3.3', 'gdown >= 4.4.0', From 28ffb64d28034afe62d312c585d07d15590fff78 Mon Sep 17 00:00:00 2001 From: Ben Savitzky Date: Thu, 29 Jun 2023 20:45:48 -0700 Subject: [PATCH 091/362] adds coords axes. Adds two_fold_symm -> @property --- py4DSTEM/process/polar/polar_datacube.py | 50 +++++++++++++++++------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index c8afa7609..50fba3de8 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -21,7 +21,7 @@ def __init__( mask = None, mask_thresh = 0.25, ellipse = True, - two_fold_rotation = False, + two_fold_symmetry = False, ): """ Parameters @@ -29,14 +29,15 @@ def __init__( datacube : DataCube The datacube in cartesian coordinates qmin : number - Minumum radius of the polar transformation + Minumum radius of the polar transformation, in pixels qmax : number or None - Maximum radius of the polar transformation + Maximum radius of the polar transformation, in pixels qstep : number - Width of radial bins + Width of radial bins, in pixels n_annular : integer Number of bins in the annular direction. Bins will each - have a width of 360/num_annular_bins, in degrees + have a width of 360/n_annular, or 180/n_annular if + two_fold_rotation is set to True, in degrees qscale : number or None Radial scaling power to apply to polar transform mask : boolean array @@ -49,9 +50,10 @@ def __init__( performs an elliptic transform iff elliptic calibrations are available. two_fold_rotation : bool - Setting to True computes the transform mod(theta,pi), i.e. assumes all patterns - posess two-fold rotation (Friedel symmetry). The output angular range in this case - becomes [0, pi) as opposed to the default of [0,2*pi). + Setting to True computes the transform mod(theta,pi), i.e. assumes + all patterns possess two-fold rotation (Friedel symmetry). The + output angular range in this case becomes [0, pi) as opposed to the + default of [0,2*pi). """ # attach datacube @@ -68,17 +70,12 @@ def __init__( # setup sampling - # annular range, depending on if polar transform spans pi or 2*pi - if two_fold_rotation: - self._annular_range = np.pi - else: - self._annular_range = 2.0 * np.pi - # polar self._qscale = qscale if qmax is None: qmax = np.min(self._datacube.Qshape) / np.sqrt(2) - self.set_annular_bins(n_annular) + self._n_annular = n_annular + self.two_fold_symmetry = two_fold_symmetry #implicitly calls set_annular_bins self.set_radial_bins(qmin,qmax,qstep) # cartesian @@ -176,6 +173,18 @@ def annular_bins(self): @property def annular_step(self): return self._annular_step + @property + def two_fold_symmetry(self): + return self._two_fold_symmetry + @two_fold_symmetry.setter + def two_fold_symmetry(self,x): + assert(isinstance(x,bool)), f"two_fold_symmetry must be boolean, not type {type(x)}" + self._two_fold_symmetry = x + if x: + self._annular_range = np.pi + else: + self._annular_range = 2 * np.pi + self.set_annular_bins(self._n_annular) @property def n_annular(self): @@ -197,6 +206,17 @@ def set_polar_shape(self): self._sigma_KDE = self._annular_bin_step * 0.5 + # coordinate grid properties + @property + def tt(self): + return self._annular_bins + @property + def tt_deg(self): + return self._annular_bins * 180/np.pi + @property + def qq(self): + return self.radial_bins * self.calibration.get_Q_pixel_size() + # scaling property From 8b2089505118cb61982a334b30909624a259032d Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 1 Jul 2023 15:44:55 -0400 Subject: [PATCH 092/362] add custom error metrics for ptycho optimizer --- py4DSTEM/process/phase/parameter_optimize.py | 104 +++++++++++++++++-- 1 file changed, 96 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 9c1e3b297..f1f896fce 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -12,7 +12,7 @@ import numpy as np from functools import partial -from typing import Union +from typing import Union, Callable from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction from py4DSTEM.process.phase.utils import AffineTransform @@ -107,8 +107,9 @@ def __init__( def optimize( self, - n_calls: int, - n_initial_points: int, + n_calls: int = 50, + n_initial_points: int = 20, + error_metric: Union[Callable, str] = "log", **skopt_kwargs: dict, ): """ @@ -121,10 +122,29 @@ def optimize( n_initial_points: int Number of uniformly spaced trial points to test before beginning Bayesian optimization (must be less than n_calls) + error_metric: Callable or str + Function used to compute the reconstruction error. + When passed as a string, may be one of: + 'log': log(NMSE) of final object + 'linear': NMSE of final object + 'log-converged': log(NMSE) of final object if + NMSE is decreasing, 0 if NMSE increasing + 'linear-converged': NMSE of final object if + NMSE is decreasing, 1 if NMSE increasing + 'TV': sum( abs( grad( object ) ) ) / sum( abs( object ) ) + 'std': negative standard deviation of cropped object + 'std-phase': negative standard deviation of + phase of the cropped object + When passed as a Callable, a function that takes the + PhaseReconstruction object as its only argument + and returns the error metric as a single float skopt_kwargs: dict Additional arguments to be passed to skopt.gp_minimize """ + + error_metric = self._get_error_metric(error_metric) + self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -137,6 +157,7 @@ def optimize( self._affine_optimize_args, self._preprocess_optimize_args, self._reconstruction_optimize_args, + error_metric, ) # Make a progress bar @@ -270,6 +291,74 @@ def _get_scan_positions(self, affine_transform, dataset): scan_positions = scan_positions @ affine_transform.asarray() return scan_positions + def _get_error_metric(self, error_metric: Union[Callable, str]) -> Callable: + """ + Get error metric as a function, converting builtin method names + to functions + """ + + if callable(error_metric): + return error_metric + + assert error_metric in ( + "log", + "linear", + "log-converged", + "linear-converged", + "TV", + "std", + "std-phase", + ), f"Error metric {error_metric} not recognized." + + if error_metric == "log": + + def f(ptycho): + return np.log(ptycho.error) + + elif error_metric == "linear": + + def f(ptycho): + return ptycho.error + + elif error_metric == "log-converged": + + def f(ptycho): + converged = ptycho.error_iterations[-1] <= np.min( + ptycho.error_iterations + ) + return np.log(ptycho.error) if converged else 0.0 + + elif error_metric == "log-linear": + + def f(ptycho): + converged = ptycho.error_iterations[-1] <= np.min( + ptycho.error_iterations + ) + return ptycho.error if converged else 1.0 + + elif error_metric == "TV": + + def f(ptycho): + gx, gy = np.gradient(ptycho.object_cropped, axis=(-2, -1)) + obj_mag = np.sum(np.abs(ptycho.object_cropped)) + tv = np.sum(np.abs(gx)) + np.sum(np.abs(gy)) + return tv / obj_mag + + elif error_metric == "std": + + def f(ptycho): + return -np.std(ptycho.object_cropped) + + elif error_metric == "std-phase": + + def f(ptycho): + return -np.std(np.angle(ptycho.object_cropped)) + + else: + raise ValueError(f"Error metric {error_metric} not recognized.") + + return f + def _get_optimization_function( self, cls: type[PhaseReconstruction], @@ -283,6 +372,7 @@ def _get_optimization_function( affine_optimization_params: dict, preprocess_optimization_params: dict, reconstruct_optimization_params: dict, + error_metric: Callable, ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the @@ -313,9 +403,7 @@ def _get_optimization_function( affine_preprocessed, init_static_args["datacube"] ) - ptycho_preprocessed = cls(**init_args).preprocess( - **preprocess_static_args - ) + ptycho_preprocessed = cls(**init_args).preprocess(**preprocess_static_args) def obj(**kwargs): return ptycho_preprocessed @@ -329,7 +417,7 @@ def prep(ptycho, **kwargs): affine = partial(AffineTransform, **affine_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) - + # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) @@ -350,7 +438,7 @@ def f(**kwargs): prep(ptycho, **prep_args) recon(ptycho, **reco_args) - return np.log(ptycho.error) + return error_metric(ptycho) return f From c30fce506709a0c2ad147cb6dcfafb84046b66bf Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:27:41 -0400 Subject: [PATCH 093/362] docstring clarification Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 9c1e3b297..771787563 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -21,9 +21,8 @@ class PtychographyOptimizer: """ Optimize ptychographic hyperparameters with Bayesian Optimization of a - Gaussian process. Any of the arguments to the ptychographic - init-preprocess-reconstruct pipeline can be optimized over (including - boolean or other flag options) + Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical + arguments to the ptychographic init-preprocess-reconstruct pipeline can be optimized over. """ def __init__( From e86abab575fd265da93d96cd4e80923b0a353599 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:33:22 -0400 Subject: [PATCH 094/362] remove unused argument Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 771787563..04d776137 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -273,7 +273,6 @@ def _get_optimization_function( self, cls: type[PhaseReconstruction], parameter_list: list, - n_iterations: int, init_static_args: dict, affine_static_args: dict, preprocess_static_args: dict, From cd80145ff3e5ab1205ca7b71e25675c3281f6093 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:34:43 -0400 Subject: [PATCH 095/362] remove another unused argument Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 04d776137..f2a3fdf89 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -127,7 +127,6 @@ def optimize( self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, - n_calls, self._init_static_args, self._affine_static_args, self._preprocess_static_args, From 61ace431ba88cc28d6040cc79f419480b9aa05f8 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:37:14 -0400 Subject: [PATCH 096/362] update plot function Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 81 +++++++++++++++----- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index f2a3fdf89..4b2ee331b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -166,37 +166,78 @@ def callback(*args, **kwargs): def visualize( self, - gp_model=True, - convergence=False, - objective=True, - evaluations=False, + plot_gp_model=True, + plot_convergence=False, + plot_objective=True, + plot_evaluations=False, + **kwargs, ): """ Visualize optimization results Parameters ---------- - gp_model: bool + plot_gp_model: bool Display fitted Gaussian process model (only available for 1-dimensional problem) - convergence: bool + plot_convergence: bool Display convergence history - objective: bool + plot_objective: bool Display GP objective function and partial dependence plots - evaluations: bool + plot_evaluations: bool Display histograms of sampled points + kwargs: + Passed directly to the skopt plot_gassian_process/plot_objective """ - if (len(self._parameter_list) == 1) and gp_model: - plot_gaussian_process(self._skopt_result) - plt.show() - if convergence: - plot_convergence(self._skopt_result) - plt.show() - if objective: - plot_objective(self._skopt_result) - plt.show() - if evaluations: - plot_evaluations(self._skopt_result) - plt.show() + ndims = len(self._parameter_list) + if ndims == 1: + if plot_convergence: + figsize = kwargs.pop("figsize", (9, 9)) + spec = GridSpec(nrows=2,ncols=1,height_ratios=[2,1], hspace=0.15) + else: + figsize = kwargs.pop("figsize", (9, 6)) + spec = GridSpec(nrows=1,ncols=1) + + fig = plt.figure(figsize = figsize) + ax = fig.add_subplot(spec[0]) + skopt_plot_gaussian_process(self._skopt_result,ax=ax, **kwargs) + + if plot_convergence: + ax = fig.add_subplot(spec[1]) + skopt_plot_convergence(self._skopt_result,ax=ax) + + else: + if plot_convergence: + figsize = kwargs.pop("figsize", (4*ndims, 4*(ndims+0.5))) + spec = GridSpec(nrows=ndims+1,ncols=ndims,height_ratios=[2]*ndims+[1], hspace=0.15) + else: + figsize = kwargs.pop("figsize", (4*ndims, 4*ndims)) + spec = GridSpec(nrows=ndims,ncols=ndims, hspace=0.15) + + if plot_evaluations: + axs = skopt_plot_evaluations(self._skopt_result) + elif plot_objective: + cmap = kwargs.pop("cmap", 'magma') + axs = skopt_plot_objective(self._skopt_result, cmap=cmap,**kwargs) + elif plot_convergence: + skopt_plot_convergence(self._skopt_result) + return self + + fig = axs[0,0].figure + fig.set_size_inches(figsize) + for i in range(ndims): + for j in range(ndims): + ax = axs[i,j] + ax.remove() + ax.figure = fig + fig.add_axes(ax) + ax.set_subplotspec(spec[i,j]) + + if plot_convergence: + ax = fig.add_subplot(spec[ndims,:]) + skopt_plot_convergence(self._skopt_result,ax=ax) + + spec.tight_layout(fig) + return self def get_optimized_arguments(self): From 355848460585ea7905054a8f2f75b687f7217244 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:37:35 -0400 Subject: [PATCH 097/362] update plot imports Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 4b2ee331b..b35867a2a 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -2,10 +2,10 @@ from skopt import gp_minimize from skopt.space import Real, Integer, Categorical from skopt.plots import ( - plot_convergence, - plot_gaussian_process, - plot_evaluations, - plot_objective, + plot_convergence as skopt_plot_convergence, + plot_gaussian_process as skopt_plot_gaussian_process, + plot_evaluations as skopt_plot_evaluations, + plot_objective as skopt_plot_objective, ) from skopt.utils import use_named_args import matplotlib.pyplot as plt From 9e22bcc8faf69013b37029ec44cc1d8bf03df620 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:38:59 -0400 Subject: [PATCH 098/362] aesthetic preferences regarding asserts Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index b35867a2a..c9ee9a31c 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -439,12 +439,9 @@ def __init__( """ # Check input space = space.lower() - assert space in ( - "real", - "integer", - "bool", - "categorical", - ), f"Unknown Parameter type: {space}" + if space not in ("real", "integer", "bool", "categorical"): + raise ValueError(f"Unknown Parameter type: {space}") + scaling = scaling.lower() assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" From 8b094b4e261219b0ca68a5a9494ab11549e905a3 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:39:21 -0400 Subject: [PATCH 099/362] being less assertive Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c9ee9a31c..c71242b67 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -444,7 +444,8 @@ def __init__( scaling = scaling.lower() - assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + if scaling not in ("uniform", "log-uniform"): + raise ValueError(f"Unknown scaling: {scaling}") # Get the right scikit-optimize class space_map = { From 320bc7526600a27393f1daca64989140b6fa6051 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:39:51 -0400 Subject: [PATCH 100/362] you wouldn't raise an AssertionError Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c71242b67..c0ce99646 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -460,6 +460,8 @@ def __init__( if space == "bool": categories = [True, False] + if not categories: + raise ValueError("Empty list of categories!") # store necessary information self._initial_value = initial_value self._categories = categories From 200b3e56210f4a618b2e8c8f81ef435ad8e6feb8 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:40:23 -0400 Subject: [PATCH 101/362] remove another assert Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c0ce99646..ead52b9bc 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -473,7 +473,6 @@ def __init__( def _get(self, name): self._name = name if self._param_type is Categorical: - assert self._categories is not None, "Empty list of categories!" self._skopt_param = self._param_type( name=self._name, categories=self._categories ) From d2750c9ee67e998f880911b4914ca34ae825a2d4 Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 2 Jul 2023 19:38:36 -0700 Subject: [PATCH 102/362] Update circular polar transform Set theta = 0 to the x axis --- py4DSTEM/process/polar/polar_datacube.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 50fba3de8..73c519779 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -492,7 +492,7 @@ def _transform_array( # get polar coords rr = np.sqrt(x**2 + y**2) tt = np.mod( - np.arctan2(y, x) - np.pi/2, + np.arctan2(y, x), self._polarcube._annular_range) # elliptical From 19d8e011bfee63fdcba690bc9b995c3e09008f26 Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 2 Jul 2023 20:01:24 -0700 Subject: [PATCH 103/362] Updating polar transform theta = 0 set t0 x axis --- py4DSTEM/process/polar/polar_datacube.py | 36 +++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 73c519779..558947258 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -500,21 +500,29 @@ def _transform_array( # unpack ellipse a,b,theta = ellipse - # transformation matrix (elliptic cartesian -> circular cartesian) - A = (a/b)*np.cos(theta) - B = -np.sin(theta) - C = (a/b)*np.sin(theta) - D = np.cos(theta) - det = 1 / (A*D - B*C) - - # get circular cartesian coords - xc = x*D - y*B - yc = -x*C + y*A - - # get polar coords - rr = det * np.hypot(xc,yc) + # # transformation matrix (elliptic cartesian -> circular cartesian) + # A = (a/b)*np.cos(theta) + # B = -np.sin(theta) + # C = (a/b)*np.sin(theta) + # D = np.cos(theta) + # det = 1 / (A*D - B*C) + + # # get circular cartesian coords + # xc = x*D - y*B + # yc = -x*C + y*A + + # # get polar coords + # rr = det * np.hypot(xc,yc) + # tt = np.mod( + # np.arctan2(yc,xc), + # self._polarcube._annular_range) + + # Get polar coords + xc = x*np.cos(theta) + y*np.sin(theta) + yc = (y*np.cos(theta) - x*np.sin(theta))*(a/b) + rr = (b/a) * np.hypot(xc,yc) tt = np.mod( - np.arctan2(yc,xc) - np.pi/2, + np.arctan2(yc,xc) + theta, self._polarcube._annular_range) # transform to bin sampling From f70302008ac0e5d3c2923fd620ce855f60985b5a Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 2 Jul 2023 20:06:21 -0700 Subject: [PATCH 104/362] cleaning up the comments --- py4DSTEM/process/polar/polar_datacube.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 558947258..2912928d5 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -500,23 +500,6 @@ def _transform_array( # unpack ellipse a,b,theta = ellipse - # # transformation matrix (elliptic cartesian -> circular cartesian) - # A = (a/b)*np.cos(theta) - # B = -np.sin(theta) - # C = (a/b)*np.sin(theta) - # D = np.cos(theta) - # det = 1 / (A*D - B*C) - - # # get circular cartesian coords - # xc = x*D - y*B - # yc = -x*C + y*A - - # # get polar coords - # rr = det * np.hypot(xc,yc) - # tt = np.mod( - # np.arctan2(yc,xc), - # self._polarcube._annular_range) - # Get polar coords xc = x*np.cos(theta) + y*np.sin(theta) yc = (y*np.cos(theta) - x*np.sin(theta))*(a/b) From c05fe1a0393134ed914d710cbff96abf57040fdf Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 08:50:26 -0400 Subject: [PATCH 105/362] fix for george's suggestion --- py4DSTEM/process/phase/parameter_optimize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 0c420c5be..cbd83ec16 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -548,8 +548,9 @@ def __init__( if space == "bool": categories = [True, False] - if not categories: + if categories == [] and space in ("categorical", "bool"): raise ValueError("Empty list of categories!") + # store necessary information self._initial_value = initial_value self._categories = categories From 5b977fdf22171bfd04b288858a29c152b40894da Mon Sep 17 00:00:00 2001 From: cophus Date: Mon, 3 Jul 2023 07:58:41 -0700 Subject: [PATCH 106/362] Init for peak detection --- py4DSTEM/process/polar/polar_fits.py | 2 ++ py4DSTEM/process/polar/polar_peaks.py | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 py4DSTEM/process/polar/polar_peaks.py diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index ad418939f..1e45c3230 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -348,3 +348,5 @@ def amorphous_model(basis, *coefs): return int_model + + diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py new file mode 100644 index 000000000..c03e5d7db --- /dev/null +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -0,0 +1,4 @@ + +import numpy as np +import matplotlib.pyplot as plt + From 2e3547e3057783ec5037d8d847d9224d568fca1b Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 3 Jul 2023 10:31:39 -0700 Subject: [PATCH 107/362] avoid transpose --- py4DSTEM/io/filereaders/read_arina.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 1434301fe..d42eb2803 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -71,8 +71,11 @@ def read_arina( scan_height = int(nimages / scan_width) datacube = DataCube( - array_3D.reshape( - scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + np.flip( + array_3D.reshape( + scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + ), + 0, ) ) From 76c04e085e5a0b57068640f1f294d556796d7a21 Mon Sep 17 00:00:00 2001 From: Ben Savitzky Date: Mon, 3 Jul 2023 11:42:33 -0700 Subject: [PATCH 108/362] updates --- py4DSTEM/process/calibration/origin.py | 11 +- py4DSTEM/process/fit/fit.py | 161 +++++++++++++++++------ py4DSTEM/process/polar/polar_datacube.py | 3 + 3 files changed, 129 insertions(+), 46 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index bc8c0be0c..d9007b899 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -73,11 +73,12 @@ def fit_origin( ): """ Fits the position of the origin of diffraction space to a plane or parabola, - given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, optionally - masked by the Boolean array `mask`. The 2D data arrays may be passed directly as - a 2-tuple to the arg `data`, or, if `data` is either a DataCube or Calibration - instance, they will be retreived automatically. If a DataCube or Calibration are - passed, fitted origin and residuals are stored there directly. + given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, + optionally masked by the Boolean array `mask`. The 2D data arrays may be + passed directly as a 2-tuple to the arg `data`, or, if `data` is either a + DataCube or Calibration instance, they will be retreived automatically. If a + DataCube or Calibration are passed, fitted origin and residuals are stored + there directly. Args: data (2-tuple of 2d arrays): the measured origin position (qx0,qy0) diff --git a/py4DSTEM/process/fit/fit.py b/py4DSTEM/process/fit/fit.py index e3bb4d86e..5b9a5a43e 100644 --- a/py4DSTEM/process/fit/fit.py +++ b/py4DSTEM/process/fit/fit.py @@ -29,44 +29,48 @@ def fit_1D_gaussian(xdata,ydata,xmin,xmax): A,mu,sigma = scale*popt[0],popt[1],popt[2] return A,mu,sigma -def fit_2D(function, data, data_mask=None, popt=None, - robust=False, robust_steps=3, robust_thresh=2): +def fit_2D( + function, + data, + data_mask=None, + popt=None, + robust=False, + robust_steps=3, + robust_thresh=2, + ): """ - Performs a 2D fit, where the fit function takes its first input in the form of a - length 2 vector (ndarray) of (x,y) positions, followed by the remaining parameters, - and the data to fit takes the form of an (n,m) shaped array. Robust fitting can be - enabled to iteratively reject outlier data points, which have a root-mean-square - error beyond the user-specified threshold. - - Args: - function: First input should be a length 2 array xy, where (xy[0],xy[1]) are the - (x,y) coordinates - data: Data to fit, in an (n,m) shaped ndarray - data_mask: Optional parameter. If specified, must be a boolean array of the same - shape as data, specifying which elements of data to use in the fit - return_ar: Optional parameter. If False, only the fit parameters and covariance - matrix are returned. If True, return an array of the same shape as data with - the fit values. Defaults to True - popt: Optional parameter for input. If specified, should be a tuple of initial - guesses for the fit parameters. - robust: Optional parameter. If set to True, fit will be repeated with outliers - removed. - robust_steps: Optional parameter. Number of robust iterations performed after - initial fit. - robust_thresh: Optional parameter. Threshold for including points, in units of - root-mean-square (standard deviations) error of the predicted values after - fitting. + Performs a 2D fit. + + Parameters + ---------- + function : callable + Some `function( xy, **p)` where `xy` is a length 2 vector (1D np array) + specifying the pixel position (x,y), and `p` is the function parameters + data : ndarray + Some 2D array of any shape (n,m) + data_mask : None or boolean array of shape (n,m), optional + If specified, fits only the pixels in `data` where this array is True + popt : dict + Initial guess at the parameters `p` of `function`. Note that positions + in pixels (i.e. the xy positions) are linearly scaled to the space [0,1] + robust : bool + Toggles robust fitting, which iteratively rejects outlier data points + which have a root-mean-square error beyond `robust_thresh` + robust_steps : int + The number of robust fitting iterations to perform + robust_thresh : int + The robust fitting cutoff - Returns: - (3-tuple) A 3-tuple containing: - * **popt**: optimal fit parameters to function - * **pcov**: the covariance matrix - * **fit_ar**: optional. If return_ar==True, fit_ar is returned, and is an - array of the same shape as data, containing the fit values + Returns: + (popt,pcov,fit_at) : 3-tuple + The optimal fit parameters, the fitting covariance matrix, and the + the fit array with the returned `popt` params """ + # get shape shape = data.shape shape1D = [1,np.prod(shape)] + # x and y coordinates normalized from 0 to 1 x,y = np.linspace(0, 1, shape[0]),np.linspace(0, 1, shape[1]) ry,rx = np.meshgrid(y,x) @@ -78,8 +82,10 @@ def fit_2D(function, data, data_mask=None, popt=None, if robust==False: robust_steps=0 - # least squares fitting - 1st iteration + # least squares fitting for k in range(robust_steps+1): + + # in 1st iteration, set up params and mask if k == 0: if popt is None: popt = np.zeros((1,len(signature(function).parameters)-1)) @@ -87,21 +93,26 @@ def fit_2D(function, data, data_mask=None, popt=None, mask = data_mask else: mask = np.ones(shape,dtype=bool) + + # otherwise, get fitting error and add high error pixels to mask else: - fit_mean_square_error = (function(xy,*popt).reshape(shape) - data)**2 - mask = fit_mean_square_error <= np.mean(fit_mean_square_error) * robust_thresh**2 - # include user-specified mask if provided - if data_mask is not None: - mask[data_mask==False] = False + fit_mean_square_error = ( + function(xy,*popt).reshape(shape) - data)**2 + _mask = fit_mean_square_error > np.mean( + fit_mean_square_error) * robust_thresh**2 + mask[_mask] == False # perform fitting - popt, pcov = curve_fit(function, - np.vstack((rx_1D[mask.reshape(shape1D)],ry_1D[mask.reshape(shape1D)])), + popt, pcov = curve_fit( + function, + np.vstack(( + rx_1D[mask.reshape(shape1D)], + ry_1D[mask.reshape(shape1D)])), data[mask], p0=popt) fit_ar = function(xy,*popt).reshape(shape) - return popt, pcov, fit_ar + return popt, pcov, fit_ar,mask # Functions for fitting @@ -127,5 +138,73 @@ def bezier_two(xy, c00, c01, c02, c10, c11, c12, c20, c21, c22): c12*2*(1-xy[0])*xy[0] * (xy[1]**2) + \ c22 *(xy[0]**2) * (xy[1]**2) +def polar_gaussian_2D( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + C, + ): + # unpack position + t,q = tq + # set theta value to its closest periodic reflection to mu_t + #t = np.square(t-mu_t) + #t2 = np.min(np.vstack([t,1-t])) + t2 = np.square(t-mu_t) + return \ + I0 * np.exp( + - ( t2/(2*sigma_t**2) + \ + (q-mu_q)**2/(2*sigma_q**2) ) ) + C + +def fit_2D_polar_gaussian( + data, + mask = None, + p0 = None, + robust = False, + robust_steps = 3, + robust_thresh = 2, +): + """ + Fits a 2D gaussian to the pixels in `data` which are set to True in `mask`. + + The gaussian is anisotropic and oriented along (t,q), centered at + (mu_t,mu_q), has standard deviations (sigma_t,sigma_q), maximum of I0, + and a constant offset of C, and is periodic in t. + + f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + + Parameters + ---------- + data : 2d array + the data to fit + p0 : 6-tuple + initial guess at fit parameters, (I0,mu_x,mu_y,sigma_x_sigma_y,C) + mask : 2d boolean array + ignore pixels where mask is False + robust : bool + toggle robust fitting + robust_steps : int + number of robust fit iterations + robust_thresh : number + the robust fitting threshold + + Returns + ------- + (popt,pcov,fit_ar) : 3-tuple + the optimal fit parameters, the covariance matrix, and the fit array + """ + return fit_2D( + polar_gaussian_2D, + data = data, + data_mask = mask, + popt = p0, + robust = robust, + robust_steps = robust_steps, + robust_thresh = robust_thresh + ) + + diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 50fba3de8..4f9b67c61 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -204,6 +204,9 @@ def set_polar_shape(self): # set KDE params self._annular_bin_step = 1 / (self._annular_step * (self.radial_bins + self.qstep * 0.5)) self._sigma_KDE = self._annular_bin_step * 0.5 + # set array indices + self._annular_indices = np.arange(self.polar_shape[0]).astype(int) + self._radial_indices = np.arange(self.polar_shape[1]).astype(int) # coordinate grid properties From e315b7eb558a8a4997b1b0044aec83c75ca8c944 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 17:04:29 -0400 Subject: [PATCH 109/362] add entropy metric, not sure if correct --- py4DSTEM/process/phase/parameter_optimize.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index cbd83ec16..d218871e5 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -9,6 +9,7 @@ ) from skopt.utils import use_named_args import matplotlib.pyplot as plt +from matplotlib.gridspec import GridSpec import numpy as np from functools import partial @@ -347,6 +348,7 @@ def _get_error_metric(self, error_metric: Union[Callable, str]) -> Callable: "TV", "std", "std-phase", + "entropy-phase", ), f"Error metric {error_metric} not recognized." if error_metric == "log": @@ -393,6 +395,15 @@ def f(ptycho): def f(ptycho): return -np.std(np.angle(ptycho.object_cropped)) + elif error_metric == "entropy-phase": + def f(ptycho): + obj = np.angle(ptycho.object_cropped) + gx,gy = np.gradient(obj) + ghist,_,_ = np.histogram2d(gx.ravel(),gy.ravel(),bins=obj.shape,density=True) + nz = ghist > 0 + S = np.sum(ghist[nz] * np.log2(ghist[nz])) + return S + else: raise ValueError(f"Error metric {error_metric} not recognized.") From 864d46b51d86507db412f22ce1fff097eb312fdc Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 17:05:10 -0400 Subject: [PATCH 110/362] docstring --- py4DSTEM/process/phase/parameter_optimize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index d218871e5..3a4c18a50 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -135,6 +135,8 @@ def optimize( 'std': negative standard deviation of cropped object 'std-phase': negative standard deviation of phase of the cropped object + 'entropy-phase': entropy of the phase of the + cropped object When passed as a Callable, a function that takes the PhaseReconstruction object as its only argument and returns the error metric as a single float From 2f40df30381cf91384a85f2de1eb37811f6be0ca Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 3 Jul 2023 16:39:13 -0700 Subject: [PATCH 111/362] Updating polar function defaults --- py4DSTEM/classes/methods/datacube_methods.py | 2 +- py4DSTEM/process/polar/polar_fits.py | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/classes/methods/datacube_methods.py b/py4DSTEM/classes/methods/datacube_methods.py index bf347e5ae..9b4340c9d 100644 --- a/py4DSTEM/classes/methods/datacube_methods.py +++ b/py4DSTEM/classes/methods/datacube_methods.py @@ -1325,7 +1325,7 @@ def get_beamstop_mask( ) # Add to tree - self.tree( mask_beamstop ) + self.tree(x) # return if returncalc: diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index 1e45c3230..4661fc5bd 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -10,10 +10,11 @@ def fit_amorphous_ring( center, radial_range, coefs = None, + mask_dp = None, show_fit_mask = False, verbose = False, plot_result = True, - plot_log_scale = True, + plot_log_scale = False, plot_int_scale = (-3,3), figsize = (8,8), return_all_coefs = True, @@ -30,6 +31,10 @@ def fit_amorphous_ring( (x,y) center coordinates for fitting mask radial_range: np.array (radius_inner, radius_outer) radial range to perform fitting over + coefs: np.array (optional) + Array containing initial fitting coefficients for the amorphous fit. + mask_dp: np.array + Dark field mask for fitting, in addition to the radial range specified above. show_fit_mask: bool Set to true to preview the fitting mask and initial guess for the ellipse params verbose: bool @@ -66,6 +71,9 @@ def fit_amorphous_ring( ra2 >= radial_range[0]**2, ra2 <= radial_range[1]**2, ) + if mask_dp is not None: + # Logical AND the radial mask with the user-provided mask + mask = np.logical_and(mask, mask_dp) vals = im[mask] basis = np.vstack((xa[mask],ya[mask])) @@ -118,9 +126,11 @@ def fit_amorphous_ring( int_range = ( int_med + plot_int_scale[0]*int_std, int_med + plot_int_scale[1]*int_std) - im_plot = np.tile(np.clip( - (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), - 0,1),(1,1,3)) + im_plot = np.tile( + np.clip( + (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), + 0,1), + (1,1,3)) else: int_med = np.median(vals) From 872a09437d4ccc249362e52e36786535cf861d60 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 3 Jul 2023 19:59:13 -0400 Subject: [PATCH 112/362] adds BraggVectors.get_vectors method --- .../process/diskdetection/braggvectors.py | 61 ++++++++++++++++++- test/test_braggvectors.py | 27 +++++--- 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/diskdetection/braggvectors.py b/py4DSTEM/process/diskdetection/braggvectors.py index e6566a33e..1b84dc8b6 100644 --- a/py4DSTEM/process/diskdetection/braggvectors.py +++ b/py4DSTEM/process/diskdetection/braggvectors.py @@ -45,6 +45,19 @@ class BraggVectors(Custom,BraggVectorMethods,Data): >>> vects.qx,vects.qy,vects.I >>> vects['qx'],vects['qy'],vects['intensity'] + Alternatively, you can access the centered vectors in pixel units with + + >>> vects.get_vectors( + >>> scan_x, + >>> scan_y, + >>> center = bool, + >>> ellipse = bool, + >>> pixel = bool, + >>> rotate = bool + >>> ) + + which will return the vectors at scan position (scan_x,scan_y) with the + requested calibrations applied. """ def __init__( @@ -212,6 +225,46 @@ def setcal( pass + # vector getter method + + def get_vectors( + self, + scan_x, + scan_y, + center, + ellipse, + pixel, + rotate + ): + """ + Returns the bragg vectors at the specified scan position with + the specified calibration state. + + Parameters + ---------- + scan_x : int + scan_y : int + center : bool + ellipse : bool + pixel : bool + rotate : bool + + Returns + ------- + vectors : BVects + """ + ans = self._v_uncal[scan_x,scan_y].data + ans = self.cal._transform( + data = ans, + cal = self.calibration, + scanxy = (scan_x,scan_y), + center = center, + ellipse = ellipse, + pixel = pixel, + rotate = rotate, + ) + return BVects(ans) + # copy @@ -397,13 +450,16 @@ def _transform( if center: origin = cal.get_origin(x,y) + assert(origin is not None), "Requested calibration was not found!" ans['qx'] -= origin[0] ans['qy'] -= origin[1] # ellipse if ellipse: - a,b,theta = cal.get_ellipse(x,y) + ell = cal.get_ellipse(x,y) + assert(ell is not None), "Requested calibration was not found!" + a,b,theta = ell # Get the transformation matrix e = b/a sint, cost = np.sin(theta-np.pi/2.), np.cos(theta-np.pi/2.) @@ -423,6 +479,7 @@ def _transform( # pixel size if pixel: qpix = cal.get_Q_pixel_size() + assert(qpix is not None), "Requested calibration was not found!" ans['qx'] *= qpix ans['qy'] *= qpix @@ -431,6 +488,8 @@ def _transform( if rotate: flip = cal.get_QR_flip() theta = cal.get_QR_rotation_degrees() + assert(flip is not None), "Requested calibration was not found!" + assert(theta is not None), "Requested calibration was not found!" # rotation matrix R = np.array([ [np.cos(theta), -np.sin(theta)], diff --git a/test/test_braggvectors.py b/test/test_braggvectors.py index 107cf7a64..f250f7a0f 100644 --- a/test/test_braggvectors.py +++ b/test/test_braggvectors.py @@ -45,6 +45,14 @@ def setup_class(cls): # 'CUDA': True, } + # find disks + cls.braggpeaks = datacube.find_Bragg_disks( + template = probe.kernel, + **cls.detect_params, + ) + + # set an arbitrary center for testing + cls.braggpeaks.calibration.set_origin((datacube.Qshape[0]/2,datacube.Qshape[1]/2)) @@ -68,20 +76,19 @@ def test_disk_detection_selected_positions(self): **self.detect_params, ) - def test_disk_detection(self): - - braggpeaks = self.datacube.find_Bragg_disks( - template = self.probe.kernel, - **self.detect_params, - ) - + def test_BraggVectors(self): - print(braggpeaks) + print(self.braggpeaks) print() - print(braggpeaks.raw[0,0]) + print(self.braggpeaks.raw[0,0]) print() - print(braggpeaks.cal[0,0]) + print(self.braggpeaks.cal[0,0]) print() + print(self.braggpeaks.get_vectors( + scan_x=5,scan_y=5, + center=True,ellipse=False,pixel=False,rotate=False + )) + From fa576bd6bf4b93b31465187bfd8e27ba3dd5f251 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 14:39:01 -0700 Subject: [PATCH 113/362] Adding peak detection --- py4DSTEM/preprocess/preprocess.py | 6 + py4DSTEM/process/polar/__init__.py | 1 + py4DSTEM/process/polar/polar_datacube.py | 5 + py4DSTEM/process/polar/polar_fits.py | 3 - py4DSTEM/process/polar/polar_peaks.py | 285 +++++++++++++++++++++++ 5 files changed, 297 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 343c20895..8d95ccd81 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -281,6 +281,12 @@ def bin_data_diffraction( # set calibration pixel size datacube.calibration.set_Q_pixel_size(Qpixsize) + # remake Cartesian coordinate system + datacube.qyy,datacube.qxx = np.meshgrid( + np.arange(0,datacube.Q_Ny), + np.arange(0,datacube.Q_Nx) + ) + # return return datacube diff --git a/py4DSTEM/process/polar/__init__.py b/py4DSTEM/process/polar/__init__.py index 741e0c610..fcabc7f41 100644 --- a/py4DSTEM/process/polar/__init__.py +++ b/py4DSTEM/process/polar/__init__.py @@ -1,3 +1,4 @@ from py4DSTEM.process.polar.polar_datacube import PolarDatacube from py4DSTEM.process.polar.polar_fits import fit_amorphous_ring, plot_amorphous_ring +from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 1356c4a8d..72171d9a2 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -99,6 +99,10 @@ def __init__( plot_FEM_global, calculate_FEM_local, ) + from py4DSTEM.process.polar.polar_peaks import ( + find_peaks_single_pattern, + find_peaks, + ) # sampling methods + properties @@ -465,6 +469,7 @@ def _transform( ) return ans elif returnval == 'nan': + ans[mask_bool] = np.nan return ans elif returnval == 'all': return ans, ans_norm, norm_array, mask_bool diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index 4661fc5bd..82085d6fb 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -357,6 +357,3 @@ def amorphous_model(basis, *coefs): int_model[sub] += int12*np.exp(dr2[sub]/(-2*sigma2**2)) return int_model - - - diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index c03e5d7db..48969fce8 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -2,3 +2,288 @@ import numpy as np import matplotlib.pyplot as plt +from scipy.ndimage import gaussian_filter +from skimage.feature import peak_local_max +from scipy.signal import peak_prominences + +from py4DSTEM import PointList + +def find_peaks_single_pattern( + self, + x, + y, + mask = None, + sigma_annular_deg = 10.0, + sigma_radial_px = 3.0, + radial_background_subtract = True, + radial_background_thresh = 0.25, + num_peaks_max = 100, + threshold_abs = 1.0, + threshold_prom_annular = None, + threshold_prom_radial = None, + remove_masked_peaks = False, + scale_sigma = 0.25, + plot_result = True, + plot_power_scale = 1.0, + plot_scale_size = 100.0, + ): + """ + Peak detection function for polar transformations. + + Parameters + -------- + x: int + x index of diffraction pattern + y: int + y index of diffraction pattern + sigma_annular_deg: float + smoothing along the annular direction in degrees, periodic + sigma_radial_px: float + smoothing along the radial direction in pixels, not periodic + radial_background_subtract: bool + If true, subtract radial background estimate + radial_background_thresh: float + Relative order of sorted values to use as background estimate. + Setting to 0.5 is equivalent to median, 0.0 is min value. + + Returns + -------- + + """ + + + + # Convert sigma values into units of bins + sigma_annular = np.deg2rad(sigma_annular_deg) / self.annular_step + sigma_radial = sigma_radial_px / self.qstep + + # Get transformed image and normalization array + im_polar, im_polar_norm, norm_array, mask_bool = self.transform( + self._datacube.data[x,y], + mask = mask, + returnval = 'all_zeros', + ) + # Change sign convention of mask + mask_bool = np.logical_not(mask_bool) + + + # Background subtraction + if radial_background_subtract: + sig_bg = np.zeros(im_polar.shape[1]) + for a0 in range(im_polar.shape[1]): + if np.any(mask_bool[:,a0]): + vals = np.sort(im_polar[mask_bool[:,a0],a0]) + ind = np.round(radial_background_thresh * (vals.shape[0]-1)).astype('int') + sig_bg[a0] = vals[ind] + im_polar = np.maximum(im_polar - sig_bg[None,:], 0) + + # apply smoothing and normalization + im_polar_sm = gaussian_filter( + im_polar * norm_array, + sigma = (sigma_annular, sigma_radial), + mode = ('wrap', 'nearest'), + ) + im_mask = gaussian_filter( + norm_array, + sigma = (sigma_annular, sigma_radial), + mode = ('wrap', 'nearest'), + ) + sub = im_mask > 0.001 * np.max(im_mask) + im_polar_sm[sub] /= im_mask[sub] + + # Find local maxima + peaks = peak_local_max( + im_polar_sm, + num_peaks = num_peaks_max, + threshold_abs = threshold_abs, + ) + + # check if peaks should be removed from the polar transformation mask + if remove_masked_peaks: + peaks = np.delete( + peaks, + mask_bool[peaks[:,0],peaks[:,1]] == False, + axis = 0, + ) + + # peak intensity + peaks_int = im_polar_sm[peaks[:,0],peaks[:,1]] + + # Estimate prominance of peaks, and their size in units of pixels + peaks_prom = np.zeros((peaks.shape[0],4)) + annular_ind_center = np.atleast_1d(np.array(im_polar_sm.shape[0]//2).astype('int')) + for a0 in range(peaks.shape[0]): + + # annular + trace_annular = np.roll( + np.squeeze(im_polar_sm[:,peaks[a0,1]]), + annular_ind_center - peaks[a0,0]) + p_annular = peak_prominences( + trace_annular, + annular_ind_center, + ) + sigma_annular = scale_sigma * np.maximum( + annular_ind_center - p_annular[1], + p_annular[2] - annular_ind_center) + + # radial + trace_radial = im_polar_sm[peaks[a0,0],:] + p_radial = peak_prominences( + trace_radial, + np.atleast_1d(peaks[a0,1]), + ) + sigma_radial = scale_sigma * np.maximum( + peaks[a0,1] - p_radial[1], + p_radial[2] - peaks[a0,1]) + + # output + peaks_prom[a0,0] = p_annular[0] + peaks_prom[a0,1] = sigma_annular[0] + peaks_prom[a0,2] = p_radial[0] + peaks_prom[a0,3] = sigma_radial[0] + + # if needed, remove peaks using prominance criteria + if threshold_prom_annular is not None: + remove = peaks_prom[:,0] < threshold_prom_annular + peaks = np.delete( + peaks, + remove, + axis = 0, + ) + peaks_int = np.delete( + peaks_int, + remove, + ) + peaks_prom = np.delete( + peaks_prom, + remove, + axis = 0, + ) + if threshold_prom_radial is not None: + remove = peaks_prom[:,2] < threshold_prom_radial + peaks = np.delete( + peaks, + remove, + axis = 0, + ) + peaks_int = np.delete( + peaks_int, + remove, + ) + peaks_prom = np.delete( + peaks_prom, + remove, + axis = 0, + ) + + # Output data as a pointlist + # peaks_polar = np.zeros( + # peaks.shape[0], + # dtype={ + # 'names':('qt', 'qr', 'intensity', + # 'sigma_annular', 'prom_annular', + # 'sigma_radial', 'prom_radial', + # ), + # 'formats':('f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'f8')} + # ) + peaks_polar = PointList( + np.column_stack((peaks, peaks_int, peaks_prom)).ravel().view([ + ('qt', np.float), + ('qr', np.float), + ('intensity', np.float), + ('prom_annular', np.float), + ('sigma_annular', np.float), + ('prom_radial', np.float), + ('sigma_radial', np.float), + ]), + name = 'peaks_polar') + + + if plot_result: + # init + im_plot = im_polar.copy() + im_plot = np.maximum(im_plot, 0) ** plot_power_scale + + t = np.linspace(0,2*np.pi,180+1) + ct = np.cos(t) + st = np.sin(t) + + + fig,ax = plt.subplots(figsize=(12,6)) + + ax.imshow( + im_plot, + cmap = 'gray', + ) + + # peaks + ax.scatter( + peaks_polar['qr'], + peaks_polar['qt'], + s = peaks_polar['intensity'] * plot_scale_size, + marker='o', + color = (1,0,0), + ) + for a0 in range(peaks_polar.data.shape[0]): + ax.plot( + peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], + peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0], + linewidth = 1, + color = 'r', + ) + if peaks_polar['qt'][a0] - peaks_polar['sigma_annular'][a0] < 0: + ax.plot( + peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], + peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0] + im_plot.shape[0], + linewidth = 1, + color = 'r', + ) + if peaks_polar['qt'][a0] + peaks_polar['sigma_annular'][a0] > im_plot.shape[0]: + ax.plot( + peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], + peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0] - im_plot.shape[0], + linewidth = 1, + color = 'r', + ) + + # plot appearance + ax.set_xlim((0,im_plot.shape[1]-1)) + ax.set_ylim((im_plot.shape[0]-1,0)) + + # ax.imshow(np.hstack(( + # im_polar, + # im_polar_sm * 2, + # # np.tile(sig_bg[None,:],(im_polar.shape[0],1)) + # )), + # cmap = 'gray', + # ) + # ax.imshow( + # im_polar_sm, + # ) + + + return peaks_polar + + + +def find_peaks( + self, + mask = None, + sigma_annular_deg = 10.0, + sigma_radial_px = 2.0, + ): + """ + Peak detection function for polar transformations. + + Parameters + -------- + sigma_annular_deg: float + smoothing along the annular direction in degrees, periodic + sigma_radial_px: float + smoothing along the radial direction in pixels, not periodic + + Returns + -------- + + """ + pass \ No newline at end of file From cc35a7c63bb94e92123f68e8a85975c9c4940876 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 15:50:41 -0700 Subject: [PATCH 114/362] Adding new function stems --- py4DSTEM/process/polar/__init__.py | 3 +- py4DSTEM/process/polar/polar_datacube.py | 4 + py4DSTEM/process/polar/polar_peaks.py | 166 +++++++++++++++++++---- 3 files changed, 145 insertions(+), 28 deletions(-) diff --git a/py4DSTEM/process/polar/__init__.py b/py4DSTEM/process/polar/__init__.py index fcabc7f41..ddf0a9e50 100644 --- a/py4DSTEM/process/polar/__init__.py +++ b/py4DSTEM/process/polar/__init__.py @@ -1,4 +1,3 @@ from py4DSTEM.process.polar.polar_datacube import PolarDatacube from py4DSTEM.process.polar.polar_fits import fit_amorphous_ring, plot_amorphous_ring -from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks - +from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks, refine_peaks, plot_radial_peaks, plot_radial_background, make_orientation_histogram diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 72171d9a2..9da003418 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -102,6 +102,10 @@ def __init__( from py4DSTEM.process.polar.polar_peaks import ( find_peaks_single_pattern, find_peaks, + refine_peaks, + plot_radial_peaks, + plot_radial_background, + make_orientation_histogram, ) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 48969fce8..807013801 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -6,13 +6,16 @@ from skimage.feature import peak_local_max from scipy.signal import peak_prominences -from py4DSTEM import PointList +# from emdfile import tqdmnd, PointList, PointListArray +from py4DSTEM import tqdmnd, PointList, PointListArray def find_peaks_single_pattern( self, x, y, mask = None, + bragg_peaks = None, + bragg_mask_radius = None, sigma_annular_deg = 10.0, sigma_radial_px = 3.0, radial_background_subtract = True, @@ -23,9 +26,11 @@ def find_peaks_single_pattern( threshold_prom_radial = None, remove_masked_peaks = False, scale_sigma = 0.25, + return_background = False, plot_result = True, plot_power_scale = 1.0, plot_scale_size = 100.0, + returnfig = False, ): """ Peak detection function for polar transformations. @@ -36,6 +41,10 @@ def find_peaks_single_pattern( x index of diffraction pattern y: int y index of diffraction pattern + mask: np.array + Boolean mask in Cartesian space, to filter detected peaks. + bragg_peaks: py4DSTEM.BraggVectors + Set of Bragg peaks used to generated a mask in Cartesian space, to filter detected peaks sigma_annular_deg: float smoothing along the annular direction in degrees, periodic sigma_radial_px: float @@ -51,6 +60,18 @@ def find_peaks_single_pattern( """ + # if needed, generate mask from Bragg peaks + if bragg_peaks is not None: + mask_bragg = self._datacube.get_braggmask( + bragg_peaks, + x, + y, + radius = bragg_mask_radius, + ) + if mask is None: + mask = mask_bragg + else: + mask = np.logical_or(mask, mask_bragg) # Convert sigma values into units of bins @@ -177,15 +198,6 @@ def find_peaks_single_pattern( ) # Output data as a pointlist - # peaks_polar = np.zeros( - # peaks.shape[0], - # dtype={ - # 'names':('qt', 'qr', 'intensity', - # 'sigma_annular', 'prom_annular', - # 'sigma_radial', 'prom_radial', - # ), - # 'formats':('f8', 'f8', 'f8', 'f8', 'f8', 'f8', 'f8')} - # ) peaks_polar = PointList( np.column_stack((peaks, peaks_int, peaks_prom)).ravel().view([ ('qt', np.float), @@ -250,30 +262,38 @@ def find_peaks_single_pattern( ax.set_xlim((0,im_plot.shape[1]-1)) ax.set_ylim((im_plot.shape[0]-1,0)) - # ax.imshow(np.hstack(( - # im_polar, - # im_polar_sm * 2, - # # np.tile(sig_bg[None,:],(im_polar.shape[0],1)) - # )), - # cmap = 'gray', - # ) - # ax.imshow( - # im_polar_sm, - # ) - - - return peaks_polar - + if returnfig and plot_result: + if return_background: + return peaks_polar, sig_bg, fig, ax + else: + return peaks_polar, fig, ax + else: + if return_background: + return peaks_polar, sig_bg + else: + return peaks_polar def find_peaks( self, mask = None, + bragg_peaks = None, + bragg_mask_radius = None, sigma_annular_deg = 10.0, - sigma_radial_px = 2.0, + sigma_radial_px = 3.0, + radial_background_subtract = True, + radial_background_thresh = 0.25, + num_peaks_max = 100, + threshold_abs = 1.0, + threshold_prom_annular = None, + threshold_prom_radial = None, + remove_masked_peaks = False, + scale_sigma = 0.25, + progress_bar = True, ): """ - Peak detection function for polar transformations. + Peak detection function for polar transformations. Loop through all probe positions, + find peaks. Store the peak positions and background signals. Parameters -------- @@ -285,5 +305,99 @@ def find_peaks( Returns -------- + """ + + # init + self.bragg_peaks = bragg_peaks + self.peaks = PointListArray( + dtype = [ + ('qt', ' Date: Tue, 4 Jul 2023 17:37:44 -0700 Subject: [PATCH 115/362] Adding orientation histogram outputs Links this code to the flowline module --- py4DSTEM/process/diffraction/flowlines.py | 2 +- py4DSTEM/process/polar/polar_peaks.py | 310 +++++++++++++++++++++- 2 files changed, 298 insertions(+), 14 deletions(-) diff --git a/py4DSTEM/process/diffraction/flowlines.py b/py4DSTEM/process/diffraction/flowlines.py index c2fa224fa..27d4f9381 100644 --- a/py4DSTEM/process/diffraction/flowlines.py +++ b/py4DSTEM/process/diffraction/flowlines.py @@ -15,7 +15,7 @@ def make_orientation_histogram( - bragg_peaks: PointList = None, + bragg_peaks: PointListArray = None, radial_ranges: np.ndarray = None, orientation_map = None, orientation_ind: int = 0, diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 807013801..678f8829a 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -2,9 +2,9 @@ import numpy as np import matplotlib.pyplot as plt -from scipy.ndimage import gaussian_filter -from skimage.feature import peak_local_max +from scipy.ndimage import gaussian_filter, gaussian_filter1d from scipy.signal import peak_prominences +from skimage.feature import peak_local_max # from emdfile import tqdmnd, PointList, PointListArray from py4DSTEM import tqdmnd, PointList, PointListArray @@ -87,7 +87,6 @@ def find_peaks_single_pattern( # Change sign convention of mask mask_bool = np.logical_not(mask_bool) - # Background subtraction if radial_background_subtract: sig_bg = np.zeros(im_polar.shape[1]) @@ -96,6 +95,7 @@ def find_peaks_single_pattern( vals = np.sort(im_polar[mask_bool[:,a0],a0]) ind = np.round(radial_background_thresh * (vals.shape[0]-1)).astype('int') sig_bg[a0] = vals[ind] + sig_bg_mask = np.sum(mask_bool, axis=0) >= (im_polar.shape[0]//2) im_polar = np.maximum(im_polar - sig_bg[None,:], 0) # apply smoothing and normalization @@ -264,12 +264,12 @@ def find_peaks_single_pattern( if returnfig and plot_result: if return_background: - return peaks_polar, sig_bg, fig, ax + return peaks_polar, sig_bg, sig_bg_mask, fig, ax else: return peaks_polar, fig, ax else: if return_background: - return peaks_polar, sig_bg + return peaks_polar, sig_bg, sig_bg_mask else: return peaks_polar @@ -326,16 +326,22 @@ def find_peaks( self._datacube.Rshape[1], self.radial_bins.shape[0], )) + self.background_radial_mask = np.zeros(( + self._datacube.Rshape[0], + self._datacube.Rshape[1], + self.radial_bins.shape[0], + ), dtype='bool') # Loop over probe positions for rx, ry in tqdmnd( - *bragg_peaks.shape, + self._datacube.Rshape[0], + self._datacube.Rshape[1], desc="Finding peaks", unit=" images", disable=not progress_bar, ): - polar_peaks, sig_bg = self.find_peaks_single_pattern( + polar_peaks, sig_bg, sig_bg_mask = self.find_peaks_single_pattern( rx, ry, mask = mask, @@ -357,7 +363,7 @@ def find_peaks( self.peaks[rx,ry] = polar_peaks self.background_radial[rx,ry] = sig_bg - + self.background_radial_mask[rx,ry] = sig_bg_mask def refine_peaks( @@ -374,30 +380,308 @@ def refine_peaks( def plot_radial_peaks( self, - returnfig = True, + qmin = None, + qmax = None, + qstep = None, + figsize = (8,4), + returnfig = False, ): """ Calculate and plot the total peak signal as a function of the radial coordinate. """ - pass + + # Get all peak data + vects = np.concatenate( + [self.peaks[i,j].data for i in range(self._datacube.Rshape[0]) for j in range(self._datacube.Rshape[1])]) + qr = vects['qr'] * self.calibration.get_Q_pixel_size() + intensity = vects['intensity'] + + # bins + if qmin is None: + qmin = self.qq[0] + if qmax is None: + qmax = self.qq[-1] + if qstep is None: + qstep = self.qq[1] - self.qq[0] + q_bins = np.arange(qmin,qmax,qstep) + q_num = q_bins.shape[0] + + # histogram + q_ind = (qr - qmin) / qstep + qf = np.floor(q_ind).astype("int") + dq = q_ind - qf + + sub = np.logical_and(qf >= 0, qf < q_num) + int_peaks = np.bincount( + np.floor(q_ind[sub]).astype("int"), + weights=(1 - dq[sub]) * intensity[sub], + minlength=q_num, + ) + sub = np.logical_and(q_ind >= -1, q_ind < q_num - 1) + int_peaks += np.bincount( + np.floor(q_ind[sub] + 1).astype("int"), + weights=dq[sub] * intensity[sub], + minlength=q_num, + ) + + + + # plotting + fig,ax = plt.subplots(figsize = figsize) + ax.plot( + q_bins, + int_peaks, + color = 'r', + linewidth = 2, + ) + ax.set_xlim((q_bins[0],q_bins[-1])) + ax.set_xlabel( + 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', + fontsize = 14, + ) + ax.set_ylabel( + 'Total Peak Signal', + fontsize = 14, + ) + + if returnfig: + return fig,ax + + def plot_radial_background( self, - returnfig = True, + figsize = (8,4), + returnfig = False, ): """ Calculate and plot the mean background signal, background standard deviation. """ - pass + + # mean + self.background_radial_mean = np.sum( + self.background_radial * self.background_radial_mask, + axis=(0,1)) + background_radial_mean_norm = np.sum( + self.background_radial_mask, + axis=(0,1)) + self.background_mask = \ + background_radial_mean_norm > (np.max(background_radial_mean_norm)*0.05) + self.background_radial_mean[self.background_mask] \ + /= background_radial_mean_norm[self.background_mask] + self.background_radial_mean[np.logical_not(self.background_mask)] = 0 + + # variance and standard deviation + self.background_radial_var = np.sum( + (self.background_radial - self.background_radial_mean[None,None,:])**2 \ + * self.background_radial_mask, + axis=(0,1)) + self.background_radial_var[self.background_mask] \ + /= self.background_radial_var[self.background_mask] + self.background_radial_var[np.logical_not(self.background_mask)] = 0 + self.background_radial_std = np.sqrt(self.background_radial_var) + + + fig,ax = plt.subplots(figsize = figsize) + ax.fill_between( + self.qq[self.background_mask], + self.background_radial_mean[self.background_mask] \ + - self.background_radial_std[self.background_mask], + self.background_radial_mean[self.background_mask] \ + + self.background_radial_std[self.background_mask], + color = 'r', + alpha=0.2, + ) + ax.plot( + self.qq[self.background_mask], + self.background_radial_mean[self.background_mask], + color = 'r', + linewidth = 2, + ) + ax.set_xlim((self.qq[0],self.qq[-1])) + ax.set_xlabel( + 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', + fontsize = 14, + ) + ax.set_ylabel( + 'Background Signal', + fontsize = 14, + ) + + if returnfig: + return fig,ax def make_orientation_histogram( self, + radial_ranges: np.ndarray = None, + orientation_offset_degrees: float = 0.0, + orientation_flip_sign: bool = False, + orientation_separate_bins: bool = False, + upsample_factor: float = 4.0, + theta_step_deg: float = None, + sigma_x: float = 1.0, + sigma_y: float = 1.0, + sigma_theta: float = 3.0, + normalize_intensity_image: bool = False, + normalize_intensity_stack: bool = True, + progress_bar: bool = True, ): """ Make an orientation histogram, in order to use flowline visualization of orientation maps. + Use peaks attached to polardatacube. + + NOTE - currently assumes two fold rotation symmetry + TODO - add support for non two fold symmetry polardatacube + + Args: + radial_ranges (np array): Size (N x 2) array for N radial bins, or (2,) for a single bin. + orientation_offset_degrees (float): Offset for orientation angles + + orientation_separate_bins (bool): whether to place multiple angles into multiple radial bins. + upsample_factor (float): Upsample factor + theta_step_deg (float): Step size along annular direction in degrees + sigma_x (float): Smoothing in x direction before upsample + sigma_y (float): Smoothing in x direction before upsample + sigma_theta (float): Smoothing in annular direction (units of bins, periodic) + normalize_intensity_image (bool): Normalize to max peak intensity = 1, per image + normalize_intensity_stack (bool): Normalize to max peak intensity = 1, all images + progress_bar (bool): Enable progress bar + + Returns: + orient_hist (array): 4D array containing Bragg peak intensity histogram + [radial_bin x_probe y_probe theta] """ - pass \ No newline at end of file + + # coordinates + if theta_step_deg is None: + # Get angles from polardatacube + theta = self.tt + else: + theta = np.arange(0,180,theta_step_deg) * np.pi / 180.0 + dtheta = theta[1] - theta[0] + dtheta_deg = dtheta * 180 / np.pi + num_theta_bins = np.size(theta) + + # Input bins + radial_ranges = np.array(radial_ranges) + if radial_ranges.ndim == 1: + radial_ranges = radial_ranges[None,:] + radial_ranges_2 = radial_ranges**2 + num_radii = radial_ranges.shape[0] + size_input = self._datacube.shape[0:2] + + # Output size + size_output = np.round(np.array(size_input).astype('float') * upsample_factor).astype('int') + + # output init + orient_hist = np.zeros([ + num_radii, + size_output[0], + size_output[1], + num_theta_bins]) + + # Loop over all probe positions + for a0 in range(num_radii): + t = "Generating histogram " + str(a0) + # for rx, ry in tqdmnd( + # *bragg_peaks.shape, desc=t,unit=" probe positions", disable=not progress_bar + # ): + for rx, ry in tqdmnd( + *size_input, + desc=t, + unit=" probe positions", + disable=not progress_bar + ): + x = (rx + 0.5)*upsample_factor - 0.5 + y = (ry + 0.5)*upsample_factor - 0.5 + x = np.clip(x,0,size_output[0]-2) + y = np.clip(y,0,size_output[1]-2) + + xF = np.floor(x).astype('int') + yF = np.floor(y).astype('int') + dx = x - xF + dy = y - yF + + add_data = False + + q = self.peaks[rx,ry]['qr'] * self.calibration.get_Q_pixel_size() + r2 = q**2 + sub = np.logical_and(r2 >= radial_ranges_2[a0,0], r2 < radial_ranges_2[a0,1]) + if np.any(sub): + add_data = True + intensity = self.peaks[rx,ry]['intensity'][sub] + + # Angles + theta = self.peaks[rx,ry]['qt'][sub] * self.annular_step + t = theta / dtheta + + if add_data: + tF = np.floor(t).astype('int') + dt = t - tF + + orient_hist[a0,xF ,yF ,:] = orient_hist[a0,xF ,yF ,:] + \ + np.bincount(np.mod(tF ,num_theta_bins), + weights=(1-dx)*(1-dy)*(1-dt)*intensity,minlength=num_theta_bins) + orient_hist[a0,xF ,yF ,:] = orient_hist[a0,xF ,yF ,:] + \ + np.bincount(np.mod(tF+1,num_theta_bins), + weights=(1-dx)*(1-dy)*( dt)*intensity,minlength=num_theta_bins) + + orient_hist[a0,xF+1,yF ,:] = orient_hist[a0,xF+1,yF ,:] + \ + np.bincount(np.mod(tF ,num_theta_bins), + weights=( dx)*(1-dy)*(1-dt)*intensity,minlength=num_theta_bins) + orient_hist[a0,xF+1,yF ,:] = orient_hist[a0,xF+1,yF ,:] + \ + np.bincount(np.mod(tF+1,num_theta_bins), + weights=( dx)*(1-dy)*( dt)*intensity,minlength=num_theta_bins) + + orient_hist[a0,xF ,yF+1,:] = orient_hist[a0,xF ,yF+1,:] + \ + np.bincount(np.mod(tF ,num_theta_bins), + weights=(1-dx)*( dy)*(1-dt)*intensity,minlength=num_theta_bins) + orient_hist[a0,xF ,yF+1,:] = orient_hist[a0,xF ,yF+1,:] + \ + np.bincount(np.mod(tF+1,num_theta_bins), + weights=(1-dx)*( dy)*( dt)*intensity,minlength=num_theta_bins) + + orient_hist[a0,xF+1,yF+1,:] = orient_hist[a0,xF+1,yF+1,:] + \ + np.bincount(np.mod(tF ,num_theta_bins), + weights=( dx)*( dy)*(1-dt)*intensity,minlength=num_theta_bins) + orient_hist[a0,xF+1,yF+1,:] = orient_hist[a0,xF+1,yF+1,:] + \ + np.bincount(np.mod(tF+1,num_theta_bins), + weights=( dx)*( dy)*( dt)*intensity,minlength=num_theta_bins) + + # smoothing / interpolation + if (sigma_x is not None) or (sigma_y is not None) or (sigma_theta is not None): + if num_radii > 1: + print('Interpolating orientation matrices ...', end='') + else: + print('Interpolating orientation matrix ...', end='') + if sigma_x is not None and sigma_x > 0: + orient_hist = gaussian_filter1d( + orient_hist,sigma_x*upsample_factor, + mode='nearest', + axis=1, + truncate=3.0) + if sigma_y is not None and sigma_y > 0: + orient_hist = gaussian_filter1d( + orient_hist,sigma_y*upsample_factor, + mode='nearest', + axis=2, + truncate=3.0) + if sigma_theta is not None and sigma_theta > 0: + orient_hist = gaussian_filter1d( + orient_hist,sigma_theta/dtheta_deg, + mode='wrap', + axis=3, + truncate=2.0) + print(' done.') + + # normalization + if normalize_intensity_stack is True: + orient_hist = orient_hist / np.max(orient_hist) + elif normalize_intensity_image is True: + for a0 in range(num_radii): + orient_hist[a0,:,:,:] = orient_hist[a0,:,:,:] / np.max(orient_hist[a0,:,:,:]) + + return orient_hist \ No newline at end of file From b0d394f93926cdf11b662bd191652cce76e58557 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 17:39:48 -0700 Subject: [PATCH 116/362] Implementing angle modification variables --- py4DSTEM/process/polar/polar_peaks.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 678f8829a..1ac5de946 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -375,7 +375,10 @@ def refine_peaks( Optionally include background offset of the peaks. """ - pass + + # See if the intial detected peaks have been saved + + def plot_radial_peaks( @@ -518,8 +521,8 @@ def plot_radial_background( def make_orientation_histogram( self, radial_ranges: np.ndarray = None, - orientation_offset_degrees: float = 0.0, orientation_flip_sign: bool = False, + orientation_offset_degrees: float = 0.0, orientation_separate_bins: bool = False, upsample_factor: float = 4.0, theta_step_deg: float = None, @@ -539,8 +542,8 @@ def make_orientation_histogram( Args: radial_ranges (np array): Size (N x 2) array for N radial bins, or (2,) for a single bin. + orientation_flip_sign (bool): Flip the direction of theta orientation_offset_degrees (float): Offset for orientation angles - orientation_separate_bins (bool): whether to place multiple angles into multiple radial bins. upsample_factor (float): Upsample factor theta_step_deg (float): Step size along annular direction in degrees @@ -615,8 +618,12 @@ def make_orientation_histogram( add_data = True intensity = self.peaks[rx,ry]['intensity'][sub] - # Angles + # Angles of all peaks theta = self.peaks[rx,ry]['qt'][sub] * self.annular_step + if orientation_flip_sign: + theta *= -1 + theta += orientation_offset_degrees + t = theta / dtheta if add_data: From 6461a503d4ec7b65646384e59547c242e1358797 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 19:36:53 -0700 Subject: [PATCH 117/362] Testing fitting --- py4DSTEM/process/fit/fit.py | 97 +++++++++-- py4DSTEM/process/polar/polar_datacube.py | 1 + py4DSTEM/process/polar/polar_peaks.py | 213 ++++++++++++++++++++++- 3 files changed, 288 insertions(+), 23 deletions(-) diff --git a/py4DSTEM/process/fit/fit.py b/py4DSTEM/process/fit/fit.py index 5b9a5a43e..9abb713f7 100644 --- a/py4DSTEM/process/fit/fit.py +++ b/py4DSTEM/process/fit/fit.py @@ -41,6 +41,8 @@ def fit_2D( """ Performs a 2D fit. + TODO: make returning the mask optional + Parameters ---------- function : callable @@ -61,11 +63,10 @@ def fit_2D( robust_thresh : int The robust fitting cutoff - Returns: - (popt,pcov,fit_at) : 3-tuple - The optimal fit parameters, the fitting covariance matrix, and the - the fit array with the returned `popt` params + (popt,pcov,fit_at, mask) : 4-tuple + The optimal fit parameters, the fitting covariance matrix, the + the fit array with the returned `popt` params, and the mask """ # get shape shape = data.shape @@ -112,7 +113,7 @@ def fit_2D( p0=popt) fit_ar = function(xy,*popt).reshape(shape) - return popt, pcov, fit_ar,mask + return popt, pcov, fit_ar, mask # Functions for fitting @@ -158,6 +159,49 @@ def polar_gaussian_2D( - ( t2/(2*sigma_t**2) + \ (q-mu_q)**2/(2*sigma_q**2) ) ) + C + +def polar_twofold_gaussian_2D( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + ): + + # unpack position + t,q = tq + + # theta periodicity + dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 + + # output intensity + return I0 * np.exp( + (dt**2 / (-2.0*sigma_t**2)) + \ + ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) + +def polar_twofold_gaussian_2D_background( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + C, + ): + + # unpack position + t,q = tq + + # theta periodicity + dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 + + # output intensity + return C + I0 * np.exp( + (dt**2 / (-2.0*sigma_t**2)) + \ + ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) + + def fit_2D_polar_gaussian( data, mask = None, @@ -165,15 +209,22 @@ def fit_2D_polar_gaussian( robust = False, robust_steps = 3, robust_thresh = 2, -): + constant_background = False, + ): """ + + NOTE - this cannot work without using pixel coordinates - something is wrong in the workflow. + + Fits a 2D gaussian to the pixels in `data` which are set to True in `mask`. The gaussian is anisotropic and oriented along (t,q), centered at (mu_t,mu_q), has standard deviations (sigma_t,sigma_q), maximum of I0, - and a constant offset of C, and is periodic in t. + and an optional constant offset of C, and is periodic in t. f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + or + f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + C Parameters ---------- @@ -189,21 +240,35 @@ def fit_2D_polar_gaussian( number of robust fit iterations robust_thresh : number the robust fitting threshold + constant_background : bool + whether or not to include constant background Returns ------- (popt,pcov,fit_ar) : 3-tuple the optimal fit parameters, the covariance matrix, and the fit array """ - return fit_2D( - polar_gaussian_2D, - data = data, - data_mask = mask, - popt = p0, - robust = robust, - robust_steps = robust_steps, - robust_thresh = robust_thresh - ) + + if constant_background: + return fit_2D( + polar_twofold_gaussian_2D_background, + data = data, + data_mask = mask, + popt = p0, + robust = robust, + robust_steps = robust_steps, + robust_thresh = robust_thresh + ) + else: + return fit_2D( + polar_twofold_gaussian_2D, + data = data, + data_mask = mask, + popt = p0, + robust = robust, + robust_steps = robust_steps, + robust_thresh = robust_thresh + ) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 9da003418..4610364a9 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -126,6 +126,7 @@ def set_radial_bins( self._qstep ) self.qscale = self._qscale + self._radial_step = self._datacube.calibration.get_Q_pixel_size() * self._qstep self.set_polar_shape() @property diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 1ac5de946..e2c32f11a 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -5,9 +5,11 @@ from scipy.ndimage import gaussian_filter, gaussian_filter1d from scipy.signal import peak_prominences from skimage.feature import peak_local_max +from scipy.optimize import curve_fit # from emdfile import tqdmnd, PointList, PointListArray from py4DSTEM import tqdmnd, PointList, PointListArray +# from py4DSTEM.process.fit import fit_2D_polar_gaussian def find_peaks_single_pattern( self, @@ -309,6 +311,7 @@ def find_peaks( # init self.bragg_peaks = bragg_peaks + self.bragg_mask_radius = bragg_mask_radius self.peaks = PointListArray( dtype = [ ('qt', '= radial_ranges_2[a0,0], r2 < radial_ranges_2[a0,1]) if np.any(sub): @@ -619,7 +818,7 @@ def make_orientation_histogram( intensity = self.peaks[rx,ry]['intensity'][sub] # Angles of all peaks - theta = self.peaks[rx,ry]['qt'][sub] * self.annular_step + theta = self.peaks[rx,ry]['qt'][sub] * self._annular_step if orientation_flip_sign: theta *= -1 theta += orientation_offset_degrees From 95729757fdf165c2cd28ecd96e7c944e520daeae Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 19:45:02 -0700 Subject: [PATCH 118/362] fixing outputs --- py4DSTEM/process/polar/polar_peaks.py | 65 ++++++--------------------- 1 file changed, 14 insertions(+), 51 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index e2c32f11a..3b4893587 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -405,8 +405,8 @@ def refine_peaks( self.peaks_init = self.peaks.copy() # coordinate scaling - dt = self._annular_step - dq = self._radial_step + t_step = self._annular_step + q_step = self._radial_step # Coordinate array for the fit qq,tt = np.meshgrid( @@ -422,8 +422,8 @@ def refine_peaks( for rx, ry in tqdmnd( # 1,#self._datacube.Rshape[0], # 1,#self._datacube.Rshape[1], - range(11,12), - range(11,12), + range(21,22), + range(21,22), desc="Refining peaks ", unit=" images", disable=not progress_bar, @@ -463,15 +463,15 @@ def refine_peaks( p = self.peaks[rx,ry] # loop over peaks - for a0 in range(1,2):#p.data.shape[0]): + for a0 in range(p.data.shape[0]): if radial_background_subtract: p0 = [ p['intensity'][a0], - p['qt'][a0] * dt, - p['qr'][a0] * dq, - p['sigma_annular'][a0] * dt, - p['sigma_radial'][a0] * dq, + p['qt'][a0] * t_step, + p['qr'][a0] * q_step, + p['sigma_annular'][a0] * t_step, + p['sigma_radial'][a0] * q_step, ] dt = np.mod(tt - p0[1] + np.pi/2, np.pi) - np.pi/2 @@ -496,17 +496,6 @@ def refine_peaks( p0 = p0, # bounds = bounds, ) - # p0 = popt[0] - # print(p0) - - # p_fit = fit_2D_polar_gaussian( - # tq[:,mask_peak.ravel()], - # p0 = p0, - # constant_background = False, - # ) - # p0 = p_fit[0] - # print(p0) - im_test2 = polar_twofold_gaussian_2D( tq, @@ -524,37 +513,11 @@ def refine_peaks( im_test2 * mask_peak, ))) - # p_fit = fit_2D_polar_gaussian( - # tq, - # p0 = p0, - # constant_background = False, - # ) - - # p_new = p_fit[0] - # int0 = p_new[0] - # qt = p_new[1] / dt - # qr = p_new[2] / dq - # sigma_annular = p_new[3] / dt - # sigma_radial = p_new[4] / dq - - # print(p0) - # print() - # print(int0, qt, qr, sigma_annular, sigma_radial) - # print() - - # print(p0) - # print() - # print(p_new) - # print() - # print(p_new[0]) - # print(p['intensity'].data[a0]) - - - # p['intensity'][a0] = p_new[0], - # p['qt'][a0] = p_new[1] / dq, - # p['qr'][a0] = p_new[2] / dt, - # p['sigma_annular'][a0] = p_new[3] / dt, - # p['sigma_radial'][a0] = p_new[4] / dq, + self.peaks[rx,ry]['intensity'][a0] = p0[0] + self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step + self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step + self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step + self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step else: pass From e3c2d1e440b3bf115aaaca8bbbed9be81f05cb7d Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 4 Jul 2023 20:07:41 -0700 Subject: [PATCH 119/362] Adding constant background option --- py4DSTEM/process/polar/polar_peaks.py | 130 +++++++++++++------------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 3b4893587..6471576c7 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -9,7 +9,7 @@ # from emdfile import tqdmnd, PointList, PointListArray from py4DSTEM import tqdmnd, PointList, PointListArray -# from py4DSTEM.process.fit import fit_2D_polar_gaussian +from py4DSTEM.process.fit import polar_twofold_gaussian_2D, polar_twofold_gaussian_2D_background def find_peaks_single_pattern( self, @@ -376,6 +376,7 @@ def refine_peaks( reset_fits_to_init_positions = False, fit_range_sigma_annular = 2.0, fit_range_sigma_radial = 2.0, + min_num_pixels_fit = 10, progress_bar = True, ): """ @@ -394,6 +395,10 @@ def refine_peaks( Fit range in annular direction, in terms of the current sigma_annular fit_range_sigma_radial: float Fit range in radial direction, in terms of the current sigma_radial + min_num_pixels_fit: int + Minimum number of pixels to perform fitting + progress_bar: bool + Enable progress bar Returns -------- @@ -420,10 +425,8 @@ def refine_peaks( # Loop over probe positions for rx, ry in tqdmnd( - # 1,#self._datacube.Rshape[0], - # 1,#self._datacube.Rshape[1], - range(21,22), - range(21,22), + self._datacube.Rshape[0], + self._datacube.Rshape[1], desc="Refining peaks ", unit=" images", disable=not progress_bar, @@ -466,6 +469,7 @@ def refine_peaks( for a0 in range(p.data.shape[0]): if radial_background_subtract: + # initial parameters p0 = [ p['intensity'][a0], p['qt'][a0] * t_step, @@ -474,72 +478,71 @@ def refine_peaks( p['sigma_radial'][a0] * q_step, ] + # Mask around peak for fitting dt = np.mod(tt - p0[1] + np.pi/2, np.pi) - np.pi/2 mask_peak = np.logical_and(mask_bool, dt**2/(fit_range_sigma_annular*p0[3])**2 \ + (qq-p0[2])**2/(fit_range_sigma_radial*p0[4])**2 <= 1) - from py4DSTEM.process.fit import polar_twofold_gaussian_2D - im_test1 = polar_twofold_gaussian_2D( - tq, - p0[0], - p0[1], - p0[2], - p0[3], - p0[4], - ).reshape(im_polar.shape) - - p0, pcov = curve_fit( - polar_twofold_gaussian_2D, - tq[:,mask_peak.ravel()], - im_polar[mask_peak], - p0 = p0, - # bounds = bounds, - ) - - im_test2 = polar_twofold_gaussian_2D( - tq, - p0[0], - p0[1], - p0[2], - p0[3], - p0[4], - ).reshape(im_polar.shape) - - fig,ax = plt.subplots(figsize = (12,6)) - ax.imshow(np.hstack(( - im_polar * mask_peak, - im_test1 * mask_peak, - im_test2 * mask_peak, - ))) - - self.peaks[rx,ry]['intensity'][a0] = p0[0] - self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step - self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step - self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step - self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step + if np.sum(mask_peak) > min_num_pixels_fit: + try: + # perform fitting + p0, pcov = curve_fit( + polar_twofold_gaussian_2D, + tq[:,mask_peak.ravel()], + im_polar[mask_peak], + p0 = p0, + # bounds = bounds, + ) + + # Output parameters + self.peaks[rx,ry]['intensity'][a0] = p0[0] + self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step + self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step + self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step + self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step + + except: + pass else: - pass + # initial parameters + p0 = [ + p['intensity'][a0], + p['qt'][a0] * t_step, + p['qr'][a0] * q_step, + p['sigma_annular'][a0] * t_step, + p['sigma_radial'][a0] * q_step, + 0, + ] + + # Mask around peak for fitting + dt = np.mod(tt - p0[1] + np.pi/2, np.pi) - np.pi/2 + mask_peak = np.logical_and(mask_bool, + dt**2/(fit_range_sigma_annular*p0[3])**2 \ + + (qq-p0[2])**2/(fit_range_sigma_radial*p0[4])**2 <= 1) + if np.sum(mask_peak) > min_num_pixels_fit: + try: + # perform fitting + p0, pcov = curve_fit( + polar_twofold_gaussian_2D_background, + tq[:,mask_peak.ravel()], + im_polar[mask_peak], + p0 = p0, + # bounds = bounds, + ) - # print(p0[0]) - # print(p[0]) + # Output parameters + self.peaks[rx,ry]['intensity'][a0] = p0[0] + self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step + self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step + self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step + self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step + except: + pass - # Testing - fig,ax = plt.subplots() - ax.imshow( - im_polar**0.5, - cmap = 'gray', - ) - ax.scatter( - p['qr'], - p['qt'], - marker = '+', - color = 'r', - s = 100 - ) def plot_radial_peaks( self, @@ -589,7 +592,6 @@ def plot_radial_peaks( ) - # plotting fig,ax = plt.subplots(figsize = figsize) ax.plot( @@ -650,7 +652,7 @@ def plot_radial_background( fig,ax = plt.subplots(figsize = figsize) ax.fill_between( - self.qq[self.background_mask] * self._radial_step, + self.qq[self.background_mask], self.background_radial_mean[self.background_mask] \ - self.background_radial_std[self.background_mask], self.background_radial_mean[self.background_mask] \ @@ -665,8 +667,8 @@ def plot_radial_background( linewidth = 2, ) ax.set_xlim(( - self.qq[0] * self._radial_step, - self.qq[-1] * self._radial_step)) + self.qq[0], + self.qq[-1])) ax.set_xlabel( 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', fontsize = 14, From 29dda66561c23f3db2e700664488faaba801bf27 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 5 Jul 2023 15:20:25 -0400 Subject: [PATCH 120/362] cuda disk detec fix --- py4DSTEM/process/diskdetection/diskdetection_cuda.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/diskdetection/diskdetection_cuda.py b/py4DSTEM/process/diskdetection/diskdetection_cuda.py index 2cd96be51..df5793b47 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_cuda.py +++ b/py4DSTEM/process/diskdetection/diskdetection_cuda.py @@ -198,9 +198,9 @@ def find_Bragg_disks_CUDA( threads=threads, ) - # clean up - del batched_subcube, batched_crosscorr, subFFT, cc, ccc - cp.get_default_memory_pool().free_all_blocks() + # clean up + del batched_subcube, batched_crosscorr, subFFT, cc, ccc + cp.get_default_memory_pool().free_all_blocks() else: From 003d66d2538e4a0e44c2db3b4307fbff077ba808 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 5 Jul 2023 15:23:27 -0400 Subject: [PATCH 121/362] cuda disk detec fix --- py4DSTEM/process/diskdetection/diskdetection_cuda.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/diskdetection/diskdetection_cuda.py b/py4DSTEM/process/diskdetection/diskdetection_cuda.py index 2cd96be51..df5793b47 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_cuda.py +++ b/py4DSTEM/process/diskdetection/diskdetection_cuda.py @@ -198,9 +198,9 @@ def find_Bragg_disks_CUDA( threads=threads, ) - # clean up - del batched_subcube, batched_crosscorr, subFFT, cc, ccc - cp.get_default_memory_pool().free_all_blocks() + # clean up + del batched_subcube, batched_crosscorr, subFFT, cc, ccc + cp.get_default_memory_pool().free_all_blocks() else: From 3ec60a3ee49b8ea8c76d850a27f749e95d7e4fa9 Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 5 Jul 2023 17:06:51 -0700 Subject: [PATCH 122/362] Adding peak splitting --- py4DSTEM/process/polar/polar_peaks.py | 58 ++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 6471576c7..dda307188 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -20,6 +20,7 @@ def find_peaks_single_pattern( bragg_mask_radius = None, sigma_annular_deg = 10.0, sigma_radial_px = 3.0, + sigma_annular_deg_max = None, radial_background_subtract = True, radial_background_thresh = 0.25, num_peaks_max = 100, @@ -27,7 +28,8 @@ def find_peaks_single_pattern( threshold_prom_annular = None, threshold_prom_radial = None, remove_masked_peaks = False, - scale_sigma = 0.25, + scale_sigma_annular = 0.5, + scale_sigma_radial = 0.25, return_background = False, plot_result = True, plot_power_scale = 1.0, @@ -51,6 +53,9 @@ def find_peaks_single_pattern( smoothing along the annular direction in degrees, periodic sigma_radial_px: float smoothing along the radial direction in pixels, not periodic + sigma_annular_deg_max: float + Specify this value for the max annular sigma. Peaks larger than this will be split + into multiple peaks, depending on the ratio. radial_background_subtract: bool If true, subtract radial background estimate radial_background_thresh: float @@ -145,7 +150,7 @@ def find_peaks_single_pattern( trace_annular, annular_ind_center, ) - sigma_annular = scale_sigma * np.maximum( + sigma_annular = scale_sigma_annular * np.maximum( annular_ind_center - p_annular[1], p_annular[2] - annular_ind_center) @@ -155,7 +160,7 @@ def find_peaks_single_pattern( trace_radial, np.atleast_1d(peaks[a0,1]), ) - sigma_radial = scale_sigma * np.maximum( + sigma_radial = scale_sigma_radial * np.maximum( peaks[a0,1] - p_radial[1], p_radial[2] - peaks[a0,1]) @@ -199,9 +204,46 @@ def find_peaks_single_pattern( axis = 0, ) + # combine peaks into one array + peaks_all = np.column_stack((peaks, peaks_int, peaks_prom)) + + # Split peaks into multiple peaks if they have sigma values larger than user-specified threshold + if sigma_annular_deg_max is not None: + peaks_new = np.zeros((0,peaks_all.shape[1])) + for a0 in range(peaks_all.shape[0]): + if peaks_all[a0,4] >= (1.5*sigma_annular_deg_max): + num = np.round(peaks_all[a0,4] / sigma_annular_deg_max) + sigma_annular_new = peaks_all[a0,4] / num + + v = np.arange(num) + v -= np.mean(v) + t_new = np.mod(peaks_all[a0,0] + 2*v*sigma_annular_new, + self._n_annular) + + for a1 in range(num.astype('int')): + peaks_new = np.vstack(( + peaks_new, + np.array(( + t_new[a1], + peaks_all[a0,1], + peaks_all[a0,2], + peaks_all[a0,3], + sigma_annular_new, + peaks_all[a0,5], + peaks_all[a0,6], + )), + )) + else: + peaks_new = np.vstack(( + peaks_new, + peaks_all[a0,:] + )) + peaks_all = peaks_new + + # Output data as a pointlist peaks_polar = PointList( - np.column_stack((peaks, peaks_int, peaks_prom)).ravel().view([ + peaks_all.ravel().view([ ('qt', np.float), ('qr', np.float), ('intensity', np.float), @@ -283,6 +325,7 @@ def find_peaks( bragg_mask_radius = None, sigma_annular_deg = 10.0, sigma_radial_px = 3.0, + sigma_annular_deg_max = None, radial_background_subtract = True, radial_background_thresh = 0.25, num_peaks_max = 100, @@ -290,7 +333,8 @@ def find_peaks( threshold_prom_annular = None, threshold_prom_radial = None, remove_masked_peaks = False, - scale_sigma = 0.25, + scale_sigma_annular = 0.5, + scale_sigma_radial = 0.25, progress_bar = True, ): """ @@ -352,6 +396,7 @@ def find_peaks( bragg_mask_radius = bragg_mask_radius, sigma_annular_deg = sigma_annular_deg, sigma_radial_px = sigma_radial_px, + sigma_annular_deg_max = sigma_annular_deg_max, radial_background_subtract = radial_background_subtract, radial_background_thresh = radial_background_thresh, num_peaks_max = num_peaks_max, @@ -359,7 +404,8 @@ def find_peaks( threshold_prom_annular = threshold_prom_annular, threshold_prom_radial = threshold_prom_radial, remove_masked_peaks = remove_masked_peaks, - scale_sigma = scale_sigma, + scale_sigma_annular = scale_sigma_annular, + scale_sigma_radial = scale_sigma_radial, return_background = True, plot_result = False, ) From 104a5cd4db1a20c720a1795122fe6c4f78d4e0d4 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:24:52 -0400 Subject: [PATCH 123/362] change how optimized dict is assembled Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 43 +++++++------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index cbd83ec16..2df443d0a 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -272,12 +272,14 @@ def get_optimized_arguments(self): where the OptimizationParameter items have been replaced with the optimal values obtained from the optimizer """ - init_opt = self._replace_optimized_parameters( - self._init_args, self._parameter_list - ) - affine_opt = self._replace_optimized_parameters( - self._affine_args, self._parameter_list - ) + optimized_dict = {p.name: v for p,v in zip(self._parameter_list,self._skopt_result.x)} + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._init_args } + init_opt = self._init_args | filtered_dict + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._affine_args } + affine_opt = self._affine_args | filtered_dict + affine_transform = partial(AffineTransform, **self._affine_static_args)( **affine_opt ) @@ -285,30 +287,15 @@ def get_optimized_arguments(self): affine_transform, init_opt["datacube"] ) init_opt["initial_scan_positions"] = scan_positions - - prep_opt = self._replace_optimized_parameters( - self._preprocess_args, self._parameter_list - ) - reco_opt = self._replace_optimized_parameters( - self._reconstruction_args, self._parameter_list - ) - + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._preprocess_args } + prep_opt = self._preprocess_args | filtered_dict + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._reconstruction_args } + reco_opt = self._reconstruction_args | filtered_dict + return init_opt, prep_opt, reco_opt - def _replace_optimized_parameters(self, arg_dict, parameters): - opt_args = {} - for k, v in arg_dict.items(): - # Check for optimization parameters - if isinstance(v, OptimizationParameter): - # Find the right parameter in the list - # There is probably a better way to do this inverse mapping! - for i, p in enumerate(parameters): - if p.name == k: - opt_args[k] = self._skopt_result.x[i] - else: - opt_args[k] = v - return opt_args - def _split_static_and_optimization_vars(self, argdict): static_args = {} optimization_args = {} From 3e9fa6c6c475a1b403dce42f97d704d19c357543 Mon Sep 17 00:00:00 2001 From: cophus Date: Thu, 6 Jul 2023 15:33:13 -0700 Subject: [PATCH 124/362] Updating beamstop mask --- py4DSTEM/classes/methods/datacube_methods.py | 51 ++++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/py4DSTEM/classes/methods/datacube_methods.py b/py4DSTEM/classes/methods/datacube_methods.py index 9b4340c9d..1ba5f9ce8 100644 --- a/py4DSTEM/classes/methods/datacube_methods.py +++ b/py4DSTEM/classes/methods/datacube_methods.py @@ -1252,8 +1252,11 @@ def find_Bragg_disks( def get_beamstop_mask( self, threshold = 0.25, - distance_edge = 4.0, + distance_edge = 2.0, include_edges = True, + sigma = 0, + use_max_dp = False, + scale_radial = None, name = "mask_beamstop", returncalc = True, ): @@ -1268,6 +1271,12 @@ def get_beamstop_mask( distance_edge (float): How many pixels to expand the mask. include_edges (bool): If set to True, edge pixels will be included in the mask. + sigma (float): + Gaussain blur std to apply to image before thresholding. + use_max_dp (bool): + Use the max DP instead of the mean DP. + scale_radial (float): + Scale from center of image by this factor (can help with edge) name (string): Name of the output array. returncalc (bool): Set to true to return the result. @@ -1276,19 +1285,41 @@ def get_beamstop_mask( """ - # Calculate dp_mean if needed - if not "dp_mean" in self._branch.keys(): - self.get_dp_mean(); - - # normalized dp_mean - int_sort = np.sort(self.tree("dp_mean").data.ravel()) + if scale_radial is not None: + x = np.arange(self.data.shape[2]) * 2.0 / self.data.shape[2] + y = np.arange(self.data.shape[3]) * 2.0 / self.data.shape[3] + ya, xa = np.meshgrid(y - np.mean(y), x - np.mean(x)) + im_scale = 1.0 + np.sqrt(xa**2 + ya**2)*scale_radial + + # Get image for beamstop mask + if use_max_dp: + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_max(); + # im = self.tree["dp_max"].data.astype('float') + if not "dp_max" in self._branch.keys(): + self.get_dp_max(); + im = self.tree("dp_max") + else: + if not "dp_mean" in self._branch.keys(): + self.get_dp_mean(); + im = self.tree("dp_mean") + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_mean(); + # im = self.tree["dp_mean"].data.astype('float') + + # smooth and scale if needed + if sigma > 0.0: + im = gaussian_filter(im, sigma, mode='nearest') + if scale_radial is not None: + im *= im_scale + + # Calculate beamstop mask + int_sort = np.sort(im.ravel()) ind = np.round(np.clip( int_sort.shape[0]*threshold, 0,int_sort.shape[0])).astype('int') intensity_threshold = int_sort[ind] - - # Use threshold to calculate initial mask - mask_beamstop = self.tree("dp_mean").data >= intensity_threshold + mask_beamstop = im >= intensity_threshold # clean up mask mask_beamstop = np.logical_not(binary_fill_holes(np.logical_not(mask_beamstop))) From 6fd464aa42d95c5b4ff4492ddd967c6431bb5517 Mon Sep 17 00:00:00 2001 From: cophus Date: Thu, 6 Jul 2023 15:37:56 -0700 Subject: [PATCH 125/362] Fixing beamstop updates --- py4DSTEM/classes/methods/datacube_methods.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/classes/methods/datacube_methods.py b/py4DSTEM/classes/methods/datacube_methods.py index 1ba5f9ce8..54f781668 100644 --- a/py4DSTEM/classes/methods/datacube_methods.py +++ b/py4DSTEM/classes/methods/datacube_methods.py @@ -1,7 +1,7 @@ # Functions to become DataCube methods import numpy as np -from scipy.ndimage import distance_transform_edt, binary_fill_holes, gaussian_filter1d +from scipy.ndimage import distance_transform_edt, binary_fill_holes, gaussian_filter1d, gaussian_filter from scipy.interpolate import interp1d from emdfile import Array, Metadata, Node @@ -1298,11 +1298,11 @@ def get_beamstop_mask( # im = self.tree["dp_max"].data.astype('float') if not "dp_max" in self._branch.keys(): self.get_dp_max(); - im = self.tree("dp_max") + im = self.tree("dp_max").data.astype('float') else: if not "dp_mean" in self._branch.keys(): self.get_dp_mean(); - im = self.tree("dp_mean") + im = self.tree("dp_mean").data # if not "dp_mean" in self.tree.keys(): # self.get_dp_mean(); # im = self.tree["dp_mean"].data.astype('float') From 1f69562bd3c12e7a145571f8ad3ed616c67c2bfc Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Thu, 6 Jul 2023 18:44:09 -0400 Subject: [PATCH 126/362] add option to override default arguments to ptycho Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 26 +++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 2df443d0a..fbdeaae1d 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -467,19 +467,27 @@ def f(**kwargs): return f - def _set_optimizer_defaults(self): + def _set_optimizer_defaults( + verbose = False, + plot_center_of_mass = False, + plot_rotation = False, + plot_probe_overlaps = False, + progress_bar = False, + store_iterations = False, + reset = True, + ): """ - Set all of the verbose and plotting to False + Set all of the verbose and plotting to False, allowing for user-overwrite. """ - self._init_static_args["verbose"] = False + self._init_static_args["verbose"] = verbose - self._preprocess_static_args["plot_center_of_mass"] = False - self._preprocess_static_args["plot_rotation"] = False - self._preprocess_static_args["plot_probe_overlaps"] = False + self._preprocess_static_args["plot_center_of_mass"] = plot_center_of_mass + self._preprocess_static_args["plot_rotation"] = plot_rotation + self._preprocess_static_args["plot_probe_overlaps"] = plot_probe_overlaps - self._reconstruction_static_args["progress_bar"] = False - self._reconstruction_static_args["store_iterations"] = False - self._reconstruction_static_args["reset"] = True + self._reconstruction_static_args["progress_bar"] = progress_bar + self._reconstruction_static_args["store_iterations"] = store_iterations + self._reconstruction_static_args["reset"] = reset class OptimizationParameter: From c2cd3fc1809ed8ab6be7b50bed3617dbadadec8e Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Thu, 6 Jul 2023 18:47:24 -0400 Subject: [PATCH 127/362] bugfix in optimizer defaults --- py4DSTEM/process/phase/parameter_optimize.py | 1 + 1 file changed, 1 insertion(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ccaa8d88f..f871a3a0e 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -481,6 +481,7 @@ def f(**kwargs): return f def _set_optimizer_defaults( + self, verbose = False, plot_center_of_mass = False, plot_rotation = False, From b2087e7c50f545d206c3f6b6e9b3c6cbb82d020e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 6 Jul 2023 21:46:34 -0400 Subject: [PATCH 128/362] updates, mv VirtImage, mv DataCube --- py4DSTEM/__init__.py | 10 +- py4DSTEM/classes/__init__.py | 1 - py4DSTEM/classes/virtualimage.py | 54 -- py4DSTEM/data/__init__.py | 1 - py4DSTEM/datacube/__init__.py | 6 + py4DSTEM/{data => datacube}/datacube.py | 202 +---- py4DSTEM/datacube/virtualimage.py | 822 ++++++++++++++++++ py4DSTEM/io/filereaders/empad.py | 2 +- py4DSTEM/io/filereaders/read_K2.py | 2 +- py4DSTEM/io/filereaders/read_dm.py | 2 +- py4DSTEM/io/filereaders/read_mib.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_12.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_5.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_6.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_7.py | 2 +- py4DSTEM/io/legacy/legacy12/read_v0_9.py | 2 +- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 6 +- py4DSTEM/process/__init__.py | 1 - py4DSTEM/process/calibration/origin.py | 2 +- py4DSTEM/process/classification/classutils.py | 2 +- .../process/diskdetection/diskdetection.py | 3 +- .../diskdetection/probe_gen_methods.py | 2 +- .../process/phase/iterative_base_class.py | 3 +- py4DSTEM/process/phase/iterative_dpc.py | 3 +- .../iterative_singleslice_ptychography.py | 2 +- py4DSTEM/process/polar/polar_datacube.py | 2 +- py4DSTEM/process/virtualimage.py | 537 ------------ py4DSTEM/visualize/__init__.py | 1 - py4DSTEM/visualize/virtualimage.py | 129 --- py4DSTEM/visualize/vis_RQ.py | 5 +- py4DSTEM/visualize/vis_special.py | 16 +- test/test_native_io/test_single_object_io.py | 10 +- 32 files changed, 886 insertions(+), 952 deletions(-) delete mode 100644 py4DSTEM/classes/virtualimage.py create mode 100644 py4DSTEM/datacube/__init__.py rename py4DSTEM/{data => datacube}/datacube.py (88%) create mode 100644 py4DSTEM/datacube/virtualimage.py delete mode 100644 py4DSTEM/process/virtualimage.py delete mode 100644 py4DSTEM/visualize/virtualimage.py diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index de56213d0..ba086dc27 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -15,16 +15,18 @@ # processing classes from py4DSTEM.data import ( - DataCube, + Data, + Calibration, DiffractionSlice, RealSlice, QPoints, - Calibration, - Data, +) +from py4DSTEM.datacube import ( + DataCube, + VirtualImage ) from py4DSTEM.classes import ( VirtualDiffraction, - VirtualImage, ) from py4DSTEM.process.diskdetection import ( Probe, diff --git a/py4DSTEM/classes/__init__.py b/py4DSTEM/classes/__init__.py index 750c8a9bb..0bacd8a70 100644 --- a/py4DSTEM/classes/__init__.py +++ b/py4DSTEM/classes/__init__.py @@ -1,6 +1,5 @@ _emd_hook = True from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction -from py4DSTEM.classes.virtualimage import VirtualImage diff --git a/py4DSTEM/classes/virtualimage.py b/py4DSTEM/classes/virtualimage.py deleted file mode 100644 index 8a9bf8c9e..000000000 --- a/py4DSTEM/classes/virtualimage.py +++ /dev/null @@ -1,54 +0,0 @@ - -from typing import Optional -import numpy as np - -from py4DSTEM.data import RealSlice,Data - - - -class VirtualImage(RealSlice,Data): - """ - Stores a real-space shaped 2D image with metadata - indicating how this image was generated from a datacube. - """ - def __init__( - self, - data: np.ndarray, - name: Optional[str] = 'virtualimage', - ): - """ - Args: - data (np.ndarray) : the 2D data - name (str) : the name - - Returns: - A new VirtualImage instance - """ - # initialize as a RealSlice - RealSlice.__init__( - self, - data = data, - name = name, - ) - - - - # read - @classmethod - def _get_constructor_args(cls,group): - """ - Returns a dictionary of args/values to pass to the class constructor - """ - ar_constr_args = RealSlice._get_constructor_args(group) - args = { - 'data' : ar_constr_args['data'], - 'name' : ar_constr_args['name'], - } - return args - - - - - - - diff --git a/py4DSTEM/data/__init__.py b/py4DSTEM/data/__init__.py index f8cd284e5..ff9429fe0 100644 --- a/py4DSTEM/data/__init__.py +++ b/py4DSTEM/data/__init__.py @@ -2,7 +2,6 @@ from py4DSTEM.data.calibration import Calibration from py4DSTEM.data.data import Data -from py4DSTEM.data.datacube import DataCube from py4DSTEM.data.diffractionslice import DiffractionSlice from py4DSTEM.data.realslice import RealSlice from py4DSTEM.data.qpoints import QPoints diff --git a/py4DSTEM/datacube/__init__.py b/py4DSTEM/datacube/__init__.py new file mode 100644 index 000000000..f1f6e5b99 --- /dev/null +++ b/py4DSTEM/datacube/__init__.py @@ -0,0 +1,6 @@ +_emd_hook = True + +from py4DSTEM.datacube.datacube import DataCube +from py4DSTEM.datacube.virtualimage import VirtualImage + + diff --git a/py4DSTEM/data/datacube.py b/py4DSTEM/datacube/datacube.py similarity index 88% rename from py4DSTEM/data/datacube.py rename to py4DSTEM/datacube/datacube.py index dc19a9443..d5da96fc6 100644 --- a/py4DSTEM/data/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -9,10 +9,14 @@ from emdfile import Array, Metadata, Node, Root, tqdmnd from py4DSTEM.data import Data, Calibration +from py4DSTEM.datacube.virtualimage import DataCubeVirtualImager - -class DataCube(Array,Data): +class DataCube( + Array, + Data, + DataCubeVirtualImager + ): """ Storage and processing methods for 4D-STEM datasets. """ @@ -943,200 +947,6 @@ def get_dp_median( - # Virtual imaging - - def get_virtual_image( - self, - mode, - geometry, - centered = False, - calibrated = False, - shift_center = False, - verbose = True, - dask = False, - return_mask = False, - name = 'virtual_image', - returncalc = True, - test_config = False - ): - """ - Get a virtual image and store it in `datacube`s tree under `name`. - The kind of virtual image is specified by the `mode` argument. - - Args: - mode (str): defines geometry mode for calculating virtual image - options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright - field - - 'annular' or 'annulus' uses annular detector, like dark - field - - 'rectangle', 'square', 'rectangular', uses rectangular - detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, - values in - pixels argument, as follows: - - 'point': 2-tuple, (qx,qy), ints - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - - 'annular' or 'annulus': nested 2-tuple, - ((qx,qy),(radius_i,radius_o)), - - 'rectangle', 'square', 'rectangular': 4-tuple, - (xmin,xmax,ymin,ymax) - - `mask`: any boolean or floating point 2D array with the same - size as datacube.Qshape - centered (bool): if False, the origin is in the upper left corner. - If True, the origin is set to the mean origin in the datacube - calibrations, so that a bright-field image could be specified - with, e.g., geometry = ((0,0),R). The origin can set with - datacube.calibration.set_origin(). For `mode="mask"`, - has no effect. Default is False. - calibrated (bool): if True, geometry is specified in units of 'A^-1' - instead of pixels. The datacube's calibrations must have its - `"Q_pixel_units"` parameter set to "A^-1". For `mode="mask"`, has - no effect. Default is False. - shift_center (bool): if True, the mask is shifted at each real space - position to account for any shifting of the origin of the - diffraction images. The datacube's calibration['origin'] - parameter must be set. The shift applied to each pattern is the - difference between the local origin position and the mean origin - position over all patterns, rounded to the nearest integer for - speed. Default is False. - verbose (bool): if True, show progress bar - dask (bool): if True, use dask arrays - return_mask (bool): if False (default) returns a virtual image as - usual. If True, does *not* generate or return a virtual image, - instead returning the mask that would be used in virtual image - computation for any call to this function where - `shift_center = False`. Otherwise, must be a 2-tuple of integers - corresponding to a scan position (rx,ry); in this case, returns - the mask that would be used for virtual image computation at this - scan position with `shift_center` set to `True`. Setting - return_mask to True does not add anything to the datacube's tree - name (str): the output object's name - returncalc (bool): if True, returns the output - Returns: - (Optional): if returncalc is True, returns the VirtualImage - """ - # perform computation - from py4DSTEM.classes.virtualimage import VirtualImage - from py4DSTEM.process.virtualimage import get_virtual_image - im = get_virtual_image( - self, - mode = mode, - geometry = geometry, - centered = centered, - calibrated = calibrated, - shift_center = shift_center, - verbose = verbose, - dask = dask, - return_mask = return_mask, - test_config = test_config - ) - - # if a mask is requested, skip the remaining i/o functionality - if return_mask is not False: - return im - - # wrap with a py4dstem class - im = VirtualImage( - data = im, - name = name, - ) - - # add generating params as metadata - im.metadata = Metadata( - name = 'gen_params', - data = { - 'mode' : mode, - 'geometry' : geometry, - 'shift_center' : shift_center, - 'centered' : centered, - 'calibrated' : calibrated, - 'verbose' : verbose, - 'dask' : dask, - 'return_mask' : return_mask, - 'test_config' : test_config - } - ) - - # add to the tree - self.attach( im ) - - # return - if returncalc: - return im - - - # Position detector - - def position_detector( - self, - mode, - geometry, - scan_position = None, - centered = None, - calibrated = None, - shift_center = None, - invert = False, - color = 'r', - alpha = 0.7, - ): - """ - Display a diffraction space image with an overlaid mask representing - a virtual detector. - - Args: - mode: see py4DSTEM.process.get_virtual_image - geometry: see py4DSTEM.process.get_virtual_image - scan_position: if None, positions the unshifted detector over the - mean or max diffraction pattern. Otherwise, must be a tuple - (rx,ry) of ints, and a detector is positioned over the - diffraction pattern at this position, including shifts if they - would be applied for this dataset (i.e. if it contains the - appropriate calibrations) - centered (bool): if False, the origin is in the upper left corner. - If True, the origin is set to the mean origin in the datacube - calibrations, so that a bright-field image could be specified - with, e.g., geometry = ((0,0),R). The origin can set with - datacube.calibration.set_origin(). For `mode="mask"`, - has no effect. Default is False. - calibrated (bool): if True, geometry is specified in units of 'A^-1' - instead of pixels. The datacube's calibrations must have its - `"Q_pixel_units"` parameter set to "A^-1". For `mode="mask"`, has - no effect. - shift_center (bool): if True, the mask is shifted at each real space - position to account for any shifting of the origin of the - diffraction images. The datacube's calibration['origin'] - parameter must be set. The shift applied to each pattern is the - difference between the local origin position and the mean origin - position over all patterns, rounded to the nearest integer for - speed. - invert (bool): if True, invert the display mask - """ - - # parse inputs - if scan_position is None: - data = self - else: - data = (self,scan_position[0],scan_position[1]) - - # make and show visualization - from py4DSTEM.visualize import position_detector - position_detector( - data, - mode, - geometry, - centered, - calibrated, - shift_center, - invert = invert, - color = color, - alpha = alpha, - ) - - - # Probe diff --git a/py4DSTEM/datacube/virtualimage.py b/py4DSTEM/datacube/virtualimage.py new file mode 100644 index 000000000..ae0b67b62 --- /dev/null +++ b/py4DSTEM/datacube/virtualimage.py @@ -0,0 +1,822 @@ +# Methods and classes for generating virtual images + +# includes +# -------- +# VirtualImage - a container for virtual image data + metadata +# DataCubeVirtualImager - methods inherited by DataCube for virt imaging +# BraggVectorsVirtualImager - methods inherited by BraggVectors for virt imaging + + +import numpy as np +import dask.array as da +from typing import Optional + +from emdfile import tqdmnd,Metadata +from py4DSTEM.data import Calibration, RealSlice, Data +from py4DSTEM.visualize.show import show + + + +# Virtual image class +# a container for the final virtual image data/metadata + +class VirtualImage(RealSlice,Data): + """ + A container for storing virtual image data and metadata, + including the real-space shaped 2D image and metadata + indicating how this image was generated from a datacube. + """ + def __init__( + self, + data: np.ndarray, + name: Optional[str] = 'virtualimage', + ): + """ + Parameters + ---------- + data : np.ndarray + the 2D data + name : str + the name + """ + # initialize as a RealSlice + RealSlice.__init__( + self, + data = data, + name = name, + ) + + # read + @classmethod + def _get_constructor_args(cls,group): + """ + Returns a dictionary of args/values to pass to the class constructor + """ + ar_constr_args = RealSlice._get_constructor_args(group) + args = { + 'data' : ar_constr_args['data'], + 'name' : ar_constr_args['name'], + } + return args + + + + + +# DataCubeVirtualImage class +# inherited by DataCube, adding the methods performing +# virtual image computations + +class DataCubeVirtualImager: + + def __init__(self): + pass + + + def get_virtual_image( + self, + mode, + geometry, + centered = False, + calibrated = False, + shift_center = False, + verbose = True, + dask = False, + return_mask = False, + name = 'virtual_image', + returncalc = True, + test_config = False + ): + """ + Calculate a virtual image. + + The detector is determined by the combination of the `mode` and + `geometry` arguments, supporting point, circular, rectangular, + annular, and custom mask detectors. The values passed to geometry + may be given with respect to an origin at the corner of the detector + array or with respect to the calibrated center position, and in units of + pixels or real calibrated units, depending on the values of the + `centered` and `calibrated` arguments, respectively. The mask may be + shifted pattern-by-pattern to account for diffraction scan shifts using + the `shift_center` argument. + + The computed virtual image is stored in the datacube's tree, and is + also returned by default. + + Parameters + ---------- + mode : str + defines geometry mode for calculating virtual image, and the + expected input for the `geometry` argument. options: + - 'point': uses a single pixel detector + - 'circle', 'circular': uses a round detector, like bright + field + - 'annular', 'annulus': uses an annular detector, like dark + field + - 'rectangle', 'square', 'rectangular': uses rectangular + detector + - 'mask': any diffraction-space shaped 2D array, representing + a flexible detector + geometry : variable + the expected value of this argument is determined by `mode` as + follows: + - 'point': 2-tuple, (qx,qy), ints + - 'circle', 'circular': nested 2-tuple, ((qx,qy),radius), + - 'annular', 'annulus': nested 2-tuple, + ((qx,qy),(radius_i,radius_o)), + - 'rectangle', 'square', 'rectangular': 4-tuple, + (xmin,xmax,ymin,ymax) + - `mask`: any boolean or floating point 2D array with the same + size as datacube.Qshape + centered : bool + if False, the origin is in the upper left corner. If True, the origin + is set to the mean origin in the datacube calibrations, so that a + bright-field image could be specified with, e.g., geometry=((0,0),R). + The origin can set with datacube.calibration.set_origin(). For + `mode="mask"`, has no effect. Default is False. + calibrated : bool + if True, geometry is specified in units of 'A^-1' instead of pixels. + The datacube's calibrations must have its `"Q_pixel_units"` parameter + set to "A^-1". For `mode="mask"`, has no effect. Default is False. + shift_center : bool + if True, the mask is shifted at each real space position to account + for any shifting of the origin of the diffraction images. The + datacube's calibration['origin'] parameter must be set. The shift + applied to each pattern is the difference between the local origin + position and the mean origin position over all patterns, rounded to + the nearest integer for speed. Default is False. If `shift_center` is + True, `centered` is automatically set to True. + verbose : bool + toggles a progress bar + dask : bool + if True, use dask to distribute the calculation + return_mask : bool + if False (default) returns a virtual image as usual. Otherwise does + *not* compute or return a virtual image, instead finding and + returning the mask that will be used in subsequent calls to this + function using these same parameters. In this case, must be either + `True` or a 2-tuple of integers corresponding to `(rx,ry)`. If True + is passed, returns the mask used if `shift_center` is set to False. + If a 2-tuple is passed, returns the mask used at scan position + (rx,ry) if `shift_center` is set to True. Nothing is added to the + datacube's tree. + name : str + the output object's name + returncalc : bool + if True, returns the output + test_config : bool + if True, prints the Boolean values of + (`centered`,`calibrated`,`shift_center`). Does not compute the + virtual image. + + Returns + ------- + virt_im : VirtualImage (optional, if returncalc is True) + """ + # parse inputs + assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ + 'check doc strings for supported modes' + if shift_center == True: + centered = True + if test_config: + for x,y in zip(['centered','calibrated','shift_center'], + [centered,calibrated,shift_center]): + print(f"{x} = {y}") + + # Get geometry + g = self.get_calibrated_detector_geometry( + self.calibration, + mode, + geometry, + centered, + calibrated + ) + + # Get mask + mask = self.make_detector(self.Qshape, mode, g) + # if return_mask is True, skip computation + if return_mask == True and shift_center == False: + return mask + + + # Calculate virtual image + + # no center shifting + if shift_center == False: + + # single CPU + if not dask: + + # allocate space + if mask.dtype == 'complex': + virtual_image = np.zeros(self.Rshape, dtype = 'complex') + else: + virtual_image = np.zeros(self.Rshape) + # compute + for rx,ry in tqdmnd( + self.R_Nx, + self.R_Ny, + disable = not verbose, + ): + virtual_image[rx,ry] = np.sum(self.data[rx,ry]*mask) + + # dask + if dask == True: + + # set up a generalized universal function for dask distribution + def _apply_mask_dask(self,mask): + virtual_image = np.sum(np.multiply(self.data,mask), dtype=np.float64) + apply_mask_dask = da.as_gufunc( + _apply_mask_dask,signature='(i,j),(i,j)->()', + output_dtypes=np.float64, + axes=[(2,3),(0,1),()], + vectorize=True + ) + + # compute + virtual_image = apply_mask_dask(self.data, mask) + + # with center shifting + else: + + # get shifts + assert(self.calibration.get_origin_shift() is not None), "origin need to be calibrated" + qx_shift,qy_shift = self.calibration.get_origin_shift() + qx_shift = qx_shift.round().astype(int) + qy_shift = qy_shift.round().astype(int) + + # if return_mask is True, get+return the mask and skip the computation + if return_mask is not False: + try: + rx,ry = return_mask + except TypeError: + raise Exception(f"if `shift_center=True`, return_mask must be a 2-tuple of ints or False, but revieced inpute value of {return_mask}") + _mask = np.roll( + mask, + (qx_shift[rx,ry], qy_shift[rx,ry]), + axis=(0,1) + ) + return _mask + + # allocate space + if mask.dtype == 'complex': + virtual_image = np.zeros(self.Rshape, dtype = 'complex') + else: + virtual_image = np.zeros(self.Rshape) + + # loop + for rx,ry in tqdmnd( + self.R_Nx, + self.R_Ny, + disable = not verbose, + ): + # get shifted mask + _mask = np.roll( + mask, + (qx_shift[rx,ry], qy_shift[rx,ry]), + axis=(0,1) + ) + # add to output array + virtual_image[rx,ry] = np.sum(self.data[rx,ry]*_mask) + + + # data handling + + # wrap with a py4dstem class + ans = VirtualImage( + data = virtual_image, + name = name, + ) + + # add generating params as metadata + ans.metadata = Metadata( + name = 'gen_params', + data = { + 'mode' : mode, + 'geometry' : geometry, + 'centered' : centered, + 'calibrated' : calibrated, + 'shift_center' : shift_center, + 'verbose' : verbose, + 'dask' : dask, + 'return_mask' : return_mask, + 'name' : name, + 'returncalc' : True, + 'test_config' : test_config + } + ) + + # add to the tree + self.attach( ans ) + + # return + if returncalc: + return ans + + + + + # Position detector + + def position_detector( + self, + mode, + geometry, + data = None, + centered = None, + calibrated = None, + shift_center = None, + scan_position = None, + invert = False, + color = 'r', + alpha = 0.7, + **kwargs + ): + """ + Position a virtual detector by displaying a mask over a diffraction + space image. Calling `.get_virtual_image()` using the same `mode` + and `geometry` parameters will compute a virtual image using this + detector. + + Parameters + ---------- + mode : str + see the DataCube.get_virtual_image docstring + geometry : variable + see the DataCube.get_virtual_image docstring + data : None or 2d-array or 2-tuple of ints + The diffraction image to overlay the mask on. If `None` (default), + looks for a max or mean or median diffraction image in this order + and if found, uses it, otherwise, uses the diffraction pattern at + scan position (0,0). If a 2d array is passed, must be diffraction + space shaped array. If a 2-tuple is passed, uses the diffraction + pattern at scan position (rx,ry). + centered : bool + see the DataCube.get_virtual_image docstring + calibrated : bool + see the DataCube.get_virtual_image docstring + shift_center : None or bool or 2-tuple of ints + If `None` (default) and `data` is either None or an array, the mask + is not shifted. If `None` and `data` is a 2-tuple, shifts the mask + according to the origin at the scan position (rx,ry) specified in + `data`. If False, does not shift the mask. If True and `data` is + a 2-tuple, shifts the mask accordingly, and if True and `data` is + any other value, raises an error. If `shift_center` is a 2-tuple, + shifts the mask according to the origin value at this 2-tuple + regardless of the value of `data` (enabling e.g. overlaying the + mask for a specific scan position on a max or mean diffraction + image.) + invert : bool + if True, invert the masked pixel (i.e. pixels *outside* the detector + are overlaid with a mask) + color : any matplotlib color specification + the mask color + alpha : number + the mask transparency + kwargs : dict + Any additional arguments are passed on to the show() function + """ + # parse inputs + + # mode + assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ + 'check doc strings for supported modes' + + # data + if data is None: + keys = ['dp_mean','dp_max','dp_median'] + for k in keys: + image = None + try: + image = data.tree(k) + break + except: + pass + if image is None: + image = self[0,0] + elif isinstance(data, np.ndarray): + assert(data.shape == self.Qshape), f"Can't position a detector over an image with a shape that is different from diffraction space. Diffraction space in this dataset has shape {self.Qshape} but the image passed has shape {data.shape}" + elif isinstance(data,tuple): + rx,ry = data[:2] + image = self[rx,ry] + else: + raise Exception(f"Invalid argument passed to `data`. Expected None or np.ndarray or tuple, not type {type(data)}") + + # shift center + if shift_center is None: + if isinstance(data,tuple): + shift_center = True + else: + shift_center = False + elif shift_center == True: + assert(isinstance(data,tuple)), "If shift_center is set to True, `data` should be a 2-tuple (rx,ry). To shift the detector mask while using some other input for `data`, set `shift_center` to a 2-tuple (rx,ry)" + elif isinstance(shift_center,tuple): + rx,ry = shift_center[:2] + shift_center = True + else: + shift_center = False + + + # Get the mask + + # Get geometry + g = self.get_calibrated_detector_geometry( + calibration = self.calibration, + mode = mode, + geometry = geometry, + centered = centered, + calibrated = calibrated + ) + + # Get mask + mask = self.make_detector(image.shape, mode, g) + if not(invert): + mask = np.logical_not(mask) + + # Shift center + if shift_center: + try: + rx,ry + except NameError: + raise Exception("if `shift_center` is True then `data` must be the 3-tuple (DataCube,rx,ry)") + # get shifts + assert(self.calibration.get_origin_shift() is not None), "origin shifts need to be calibrated" + qx_shift,qy_shift = cal.get_origin_shift() + qx_shift = int(np.round(qx_shift[rx,ry])) + qy_shift = int(np.round(qy_shift[rx,ry])) + mask = np.roll( + mask, + (qx_shift, qy_shift), + axis=(0,1) + ) + + # Show + show( + image, + mask = mask, + mask_color = color, + mask_alpha = alpha, + **kwargs + ) + return + + + + @staticmethod + def get_calibrated_detector_geometry( + calibration, + mode, + geometry, + centered, + calibrated + ): + """ + Determine the detector geometry in pixels, given some mode and geometry + in calibrated units, where the calibration state is specified by { + centered, calibrated} + + Parameters + ---------- + calibration : Calibration + Used to retrieve the center positions. If `None`, confirms that + centered and calibrated are False then passes, otherwise raises + an exception + mode : str + see the DataCube.get_virtual_image docstring + geometry : variable + see the DataCube.get_virtual_image docstring + centered : bool + see the DataCube.get_virtual_image docstring + calibrated : bool + see the DataCube.get_virtual_image docstring + + Returns + ------- + geo : tuple + the geometry in detector pixels + """ + # Parse inputs + g = geometry + if calibration is None: + assert calibrated is False and centered is False, "No calibration found - set a calibration or set `centered` and `calibrated` to False" + return g + else: + assert(isinstance(calibration, Calibration)) + cal = calibration + + # Get calibration metadata + if centered: + assert cal.get_qx0_mean() is not None, "origin needs to be calibrated" + x0_mean, y0_mean = cal.get_origin_mean() + + if calibrated: + assert cal['Q_pixel_units'] == 'A^-1', \ + 'check calibration - must be calibrated in A^-1 to use `calibrated=True`' + unit_conversion = cal.get_Q_pixel_size() + + + # Convert units into detector pixels + + # Shift center + if centered == True: + if mode == 'point': + g = (g[0] + x0_mean, g[1] + y0_mean) + if mode in('circle', 'circular', 'annulus', 'annular'): + g = ((g[0][0] + x0_mean, g[0][1] + y0_mean), g[1]) + if mode in('rectangle', 'square', 'rectangular') : + g = (g[0] + x0_mean, g[1] + x0_mean, g[2] + y0_mean, g[3] + y0_mean) + + # Scale by the detector pixel size + if calibrated == True: + if mode == 'point': + g = (g[0]/unit_conversion, g[1]/unit_conversion) + if mode in('circle', 'circular'): + g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), + (g[1]/unit_conversion)) + if mode in('annulus', 'annular'): + g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), + (g[1][0]/unit_conversion, g[1][1]/unit_conversion)) + if mode in('rectangle', 'square', 'rectangular') : + g = (g[0]/unit_conversion, g[1]/unit_conversion, + g[2]/unit_conversion, g[3]/unit_conversion) + + return g + + + @staticmethod + def make_detector( + shape, + mode, + geometry, + ): + ''' + Generate a 2D mask representing a detector function. + + Parameters + ---------- + shape : 2-tuple + defines shape of mask. Should be the shape of diffraction space. + mode : str + defines geometry mode for calculating virtual image. See the + docstring for DataCube.get_virtual_image + geometry : variable + defines geometry for calculating virtual image. See the + docstring for DataCube.get_virtual_image + + Returns + ------- + detector_mask : 2d array + ''' + g = geometry + + #point mask + if mode == 'point': + assert(isinstance(g,tuple) and len(g)==2), 'specify qx and qy as tuple (qx, qy)' + mask = np.zeros(shape, dtype=bool) + + qx = int(g[0]) + qy = int(g[1]) + + mask[qx,qy] = 1 + + #circular mask + if mode in('circle', 'circular'): + assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and isinstance(g[1],(float,int))), \ + 'specify qx, qy, radius_i as ((qx, qy), radius)' + + qxa, qya = np.indices(shape) + mask = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1] ** 2 + + #annular mask + if mode in('annulus', 'annular'): + assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and len(g[1])==2), \ + 'specify qx, qy, radius_i, radius_0 as ((qx, qy), (radius_i, radius_o))' + + assert g[1][1] > g[1][0], "Inner radius must be smaller than outer radius" + + qxa, qya = np.indices(shape) + mask1 = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 > g[1][0] ** 2 + mask2 = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1][1] ** 2 + mask = np.logical_and(mask1, mask2) + + #rectangle mask + if mode in('rectangle', 'square', 'rectangular') : + assert(isinstance(g,tuple) and len(g)==4), \ + 'specify x_min, x_max, y_min, y_max as (x_min, x_max, y_min, y_max)' + mask = np.zeros(shape, dtype=bool) + + xmin = int(np.round(g[0])) + xmax = int(np.round(g[1])) + ymin = int(np.round(g[2])) + ymax = int(np.round(g[3])) + + mask[xmin:xmax, ymin:ymax] = 1 + + #flexible mask + if mode == 'mask': + assert type(g) == np.ndarray, '`geometry` type should be `np.ndarray`' + assert (g.shape == shape), 'mask and diffraction pattern shapes do not match' + mask = g + return mask + + + + + + + + + + + + + + + + + +# TODO - where does this go? + +def make_bragg_mask( + Qshape, + g1, + g2, + radius, + origin, + max_q, + return_sum = True, + **kwargs, + ): + ''' + Creates and returns a mask consisting of circular disks + about the points of a 2D lattice. + + Args: + Qshape (2 tuple): the shape of diffraction space + g1,g2 (len 2 array or tuple): the lattice vectors + radius (number): the disk radius + origin (len 2 array or tuple): the origin + max_q (nuumber): the maxima distance to tile to + return_sum (bool): if False, return a 3D array, where each + slice contains a single disk; if False, return a single + 2D masks of all disks + + Returns: + (2 or 3D array) the mask + ''' + nas = np.asarray + g1,g2,origin = nas(g1),nas(g2),nas(origin) + + # Get N,M, the maximum indices to tile out to + L1 = np.sqrt(np.sum(g1**2)) + H = int(max_q/L1) + 1 + L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) + K = int(max_q/L2) + 1 + + # Compute number of points + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + N += 1 + + #create mask + mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + center = origin + v + mask[:,:,N] = make_detector( + Qshape, + mode = 'circle', + geometry = (center, radius), + ) + N += 1 + + + if return_sum: + mask = np.sum(mask, axis = 2) + return mask + + + +# TODO - these need to move elsewhere! + +def get_virtual_image_pointlistarray( + peaks, + mode = None, + geometry = None, + ): + """ + Make a virtual image from a pointlist array. + TODO - implement more virtual detectors. + + Args: + peaks (PointListArray): List of all peaks and intensities. + mode (str) : defines geometry mode for calculating virtual image. + Options: + - 'circular' or 'circle' uses round detector, like bright field + - 'annular' or 'annulus' uses annular detector, like dark field + geometry (variable) : valid entries are determined by the `mode`, values in pixels + argument, as follows: + - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), + qx, qy and radius, are each single float or int + - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), + qx, qy, radius_i, and radius_o are each single float or integer + - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) + + Returns: + im_virtual (2D numpy array): the calculated virtual image + """ + + # Set geometry + if mode is None: + if geometry is None: + center = None + radial_range = np.array((0,np.inf)) + else: + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) + if isinstance(geometry[1], int) or isinstance(geometry[1], float): + radial_range = np.array((0,geometry[1])) + elif len(geometry[1]) == 0: + radial_range = None + else: + radial_range = np.array(geometry[1]) + elif mode == 'circular' or mode == 'circle': + radial_range = np.array((0,geometry[1])) + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) + elif mode == 'annular' or mode == 'annulus': + radial_range = np.array(geometry[1]) + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) + + + + # init + im_virtual = np.zeros(peaks.shape) + + # Generate image + for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): + p = peaks.get_pointlist(rx,ry) + if p.data.shape[0] > 0: + if radial_range is None: + im_virtual[rx,ry] = np.sum(p.data['intensity']) + else: + if center is None: + qr = np.hypot(p.data['qx'],p.data['qy']) + else: + qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) + sub = np.logical_and( + qr >= radial_range[0], + qr < radial_range[1]) + if np.sum(sub) > 0: + im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) + + return im_virtual + + +def get_virtual_image_braggvectors( + bragg_peaks, + mode = None, + geometry = None, + ): + ''' + Function to calculate virtual images from braggvectors / pointlist arrays. + TODO - implement these detectors for braggvectors + + Args: + bragg_peaks (BraggVectors) : BraggVectors class object which stores bragg peaks + mode (str) : defines geometry mode for calculating virtual image. + Options: + - 'circular' or 'circle' uses round detector, like bright field + - 'annular' or 'annulus' uses annular detector, like dark field + geometry (variable) : valid entries are determined by the `mode`, values in pixels + argument, as follows: + - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), + qx, qy and radius, are each single float or int + - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), + qx, qy, radius_i, and radius_o are each single float or integer + - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) + + Returns: + im_virtual (2D numpy array): the calculated virtual image + ''' + + virtual_image = get_virtual_image_pointlistarray( + bragg_peaks.vectors, + mode = mode, + geometry = geometry, + ) + + return virtual_image diff --git a/py4DSTEM/io/filereaders/empad.py b/py4DSTEM/io/filereaders/empad.py index 4aef6ee77..98b515863 100644 --- a/py4DSTEM/io/filereaders/empad.py +++ b/py4DSTEM/io/filereaders/empad.py @@ -8,7 +8,7 @@ import numpy as np from pathlib import Path from emdfile import tqdmnd -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.preprocess.utils import bin2D diff --git a/py4DSTEM/io/filereaders/read_K2.py b/py4DSTEM/io/filereaders/read_K2.py index cf5dd8be6..c03de98d3 100644 --- a/py4DSTEM/io/filereaders/read_K2.py +++ b/py4DSTEM/io/filereaders/read_K2.py @@ -9,7 +9,7 @@ except ImportError: pass from emdfile import tqdmnd -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube def read_gatan_K2_bin(fp, mem="MEMMAP", binfactor=1, metadata=False, **kwargs): diff --git a/py4DSTEM/io/filereaders/read_dm.py b/py4DSTEM/io/filereaders/read_dm.py index 6762ab9f8..bc41695e1 100644 --- a/py4DSTEM/io/filereaders/read_dm.py +++ b/py4DSTEM/io/filereaders/read_dm.py @@ -5,7 +5,7 @@ from ncempy.io import dm from emdfile import tqdmnd, Array -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.preprocess.utils import bin2D diff --git a/py4DSTEM/io/filereaders/read_mib.py b/py4DSTEM/io/filereaders/read_mib.py index b8e42ee4f..e9dccff90 100644 --- a/py4DSTEM/io/filereaders/read_mib.py +++ b/py4DSTEM/io/filereaders/read_mib.py @@ -3,7 +3,7 @@ # Based on the PyXEM load_mib module https://github.com/pyxem/pyxem/blob/563a3bb5f3233f46cd3e57f3cd6f9ddf7af55ad0/pyxem/utils/io_utils.py import numpy as np -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube import os def load_mib( diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_12.py b/py4DSTEM/io/legacy/legacy12/read_v0_12.py index 9622f0a0e..470e64075 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_12.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_12.py @@ -10,10 +10,10 @@ PointListArray ) from py4DSTEM.data import ( - DataCube, DiffractionSlice, RealSlice, ) +from py4DSTEM.datacube import DataCube from emdfile import tqdmnd def read_v0_12(fp, **kwargs): diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_5.py b/py4DSTEM/io/legacy/legacy12/read_v0_5.py index fa53fb7cb..ae89ba86b 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_5.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_5.py @@ -10,10 +10,10 @@ PointListArray ) from py4DSTEM.data import ( - DataCube, DiffractionSlice, RealSlice, ) +from py4DSTEM.datacube import DataCube from emdfile import tqdmnd def read_v0_5(fp, **kwargs): diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_6.py b/py4DSTEM/io/legacy/legacy12/read_v0_6.py index bec2e6d69..d3b6d0d5f 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_6.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_6.py @@ -10,10 +10,10 @@ PointListArray ) from py4DSTEM.data import ( - DataCube, DiffractionSlice, RealSlice, ) +from py4DSTEM.datacube import DataCube from emdfile import tqdmnd def read_v0_6(fp, **kwargs): diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_7.py b/py4DSTEM/io/legacy/legacy12/read_v0_7.py index 7e3b782df..34fd917f4 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_7.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_7.py @@ -10,10 +10,10 @@ PointListArray ) from py4DSTEM.data import ( - DataCube, DiffractionSlice, RealSlice, ) +from py4DSTEM.datacube import DataCube from emdfile import tqdmnd def read_v0_7(fp, **kwargs): diff --git a/py4DSTEM/io/legacy/legacy12/read_v0_9.py b/py4DSTEM/io/legacy/legacy12/read_v0_9.py index 71bf7adaf..37e995871 100644 --- a/py4DSTEM/io/legacy/legacy12/read_v0_9.py +++ b/py4DSTEM/io/legacy/legacy12/read_v0_9.py @@ -10,10 +10,10 @@ PointListArray ) from py4DSTEM.data import ( - DataCube, DiffractionSlice, RealSlice, ) +from py4DSTEM.datacube import DataCube from emdfile import tqdmnd def read_v0_9(fp, **kwargs): diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index c9509d9f3..5ac2a843a 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -39,13 +39,15 @@ from py4DSTEM.data import ( Calibration, - DataCube, DiffractionSlice, RealSlice, QPoints, ) +from py4DSTEM.datacube import ( + DataCube, + VirtualImage +) from py4DSTEM.classes import ( - VirtualImage, VirtualDiffraction, ) from py4DSTEM.process.diskdetection import BraggVectors, Probe diff --git a/py4DSTEM/process/__init__.py b/py4DSTEM/process/__init__.py index da88ec4ba..510870f50 100644 --- a/py4DSTEM/process/__init__.py +++ b/py4DSTEM/process/__init__.py @@ -2,7 +2,6 @@ from py4DSTEM.process import diskdetection from py4DSTEM.process import virtualdiffraction -from py4DSTEM.process import virtualimage from py4DSTEM.process import latticevectors from py4DSTEM.process import phase from py4DSTEM.process import calibration diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index b3a141231..0b27f5a85 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -6,7 +6,7 @@ from scipy.optimize import leastsq from emdfile import tqdmnd, PointListArray -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.process.calibration.probe import get_probe_size from py4DSTEM.process.fit import plane,parabola,bezier_two,fit_2D from py4DSTEM.process.utils import get_CoM, add_to_2D_array_from_floats, get_maxima_2D diff --git a/py4DSTEM/process/classification/classutils.py b/py4DSTEM/process/classification/classutils.py index b2381c26f..bd4d0a053 100644 --- a/py4DSTEM/process/classification/classutils.py +++ b/py4DSTEM/process/classification/classutils.py @@ -3,7 +3,7 @@ import numpy as np from emdfile import tqdmnd, PointListArray -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.process.utils import get_shifted_ar def get_class_DP(datacube, class_image, thresh=0.01, xshifts=None, yshifts=None, diff --git a/py4DSTEM/process/diskdetection/diskdetection.py b/py4DSTEM/process/diskdetection/diskdetection.py index 1c7916a51..077b267f7 100644 --- a/py4DSTEM/process/diskdetection/diskdetection.py +++ b/py4DSTEM/process/diskdetection/diskdetection.py @@ -6,7 +6,8 @@ from emdfile import tqdmnd from py4DSTEM.process.diskdetection.braggvectors import BraggVectors -from py4DSTEM.data import DataCube, QPoints +from py4DSTEM.data import QPoints +from py4DSTEM.datacube import DataCube from py4DSTEM.preprocess.utils import get_maxima_2D from py4DSTEM.process.utils.cross_correlate import get_cross_correlation_FT from py4DSTEM.process.diskdetection.diskdetection_aiml import find_Bragg_disks_aiml diff --git a/py4DSTEM/process/diskdetection/probe_gen_methods.py b/py4DSTEM/process/diskdetection/probe_gen_methods.py index 8e7b1d717..e40208a11 100644 --- a/py4DSTEM/process/diskdetection/probe_gen_methods.py +++ b/py4DSTEM/process/diskdetection/probe_gen_methods.py @@ -5,7 +5,7 @@ binary_opening, binary_dilation, distance_transform_edt) from emdfile import tqdmnd -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.process.diskdetection import Probe from py4DSTEM.process.utils import get_shifted_ar, get_shift diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 42e207d97..e3dfa1cd7 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -18,7 +18,8 @@ cp = None from emdfile import Array, Custom, Metadata, _read_metadata, tqdmnd -from py4DSTEM.data import Calibration, DataCube +from py4DSTEM.data import Calibration +from py4DSTEM.datacube import DataCube from py4DSTEM.process.calibration import fit_origin from py4DSTEM.process.phase.iterative_ptychographic_constraints import ( PtychographicConstraints, diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 16381c4d8..ca0cdf10d 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -17,7 +17,8 @@ cp = None from emdfile import Array, Custom, Metadata, _read_metadata, tqdmnd -from py4DSTEM.data import Calibration, DataCube +from py4DSTEM.data import Calibration +from py4DSTEM.datacube import DataCube from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction warnings.simplefilter(action="always", category=UserWarning) diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index ce298967d..3efe50810 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -18,7 +18,7 @@ cp = None from emdfile import Custom, tqdmnd -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.process.phase.iterative_base_class import PtychographicReconstruction from py4DSTEM.process.phase.utils import ( ComplexProbe, diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 9aa93d678..f1d4277fb 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -1,5 +1,5 @@ import numpy as np -from py4DSTEM.data import DataCube +from py4DSTEM.datacube import DataCube from scipy.ndimage import binary_opening,binary_closing, gaussian_filter1d diff --git a/py4DSTEM/process/virtualimage.py b/py4DSTEM/process/virtualimage.py deleted file mode 100644 index d6fe79566..000000000 --- a/py4DSTEM/process/virtualimage.py +++ /dev/null @@ -1,537 +0,0 @@ -# Functions for generating virtual images -import numpy as np -import dask.array as da -from emdfile import tqdmnd -from py4DSTEM.data import Calibration - -def get_virtual_image( - datacube, - mode, - geometry, - centered = False, - calibrated = False, - shift_center = False, - verbose = True, - dask = False, - return_mask = False, - test_config = False -): - ''' - Function to calculate virtual image - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - mode (str) : defines geometry mode for calculating virtual image. - Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - - 'rectangle', 'square', 'rectangular', uses rectangular detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, values - in pixels argument, as follows: - - 'point': 2-tuple, (qx,qy), - qx and qy are each single float or int to define center - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy), - (radius_i,radius_o)) - - 'rectangle', 'square', 'rectangular': a 4-tuple, - (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point - 2D array with the same shape as datacube.Qshape - centered (bool): if False (default), the origin is in the upper left - corner. If True, the mean measured origin in the datacube - calibrations is set as center. The measured origin is set with - datacube.calibration.set_origin(). In this case, for example, a - centered bright field image could be defined by - geometry = ((0,0), R). For `mode="mask"`, has no effect. - calibrated (bool): if True, geometry is specified in units of 'A^-1' - instead of pixels. The datacube's calibrations must have its - `"Q_pixel_units"` parameter set to "A^-1". For `mode="mask"`, has - no effect. - shift_center (bool): if True, the mask is shifted at each real space - position to account for any shifting of the origin of the - diffraction images. The datacube's calibration['origin'] parameter - must be set (centered = True). The shift applied to each pattern is - the difference between the local origin position and the mean origin - position over all patterns, rounded to the nearest integer for speed. - verbose (bool): if True, show progress bar - dask (bool): if True, use dask arrays - return_mask (bool or tuple): if False (default) returns a virtual image - as usual. If True, does *not* generate or return a virtual image, - instead returning the mask that would be used in virtual image - computation for any call to this function where - `shift_center = False`. Otherwise, must be a 2-tuple of integers - corresponding to a scan position (rx,ry); in this case, returns the - mask that would be used for virtual image computation at this scan - position with `shift_center` set to `True`. - test_config: if True, returns the Boolean value of (`centered`, - `calibrated`,`shift_center`). Does not compute the virtual image. - - Returns: - (2D array) virtual image - ''' - - assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ - 'check doc strings for supported modes' - if shift_center == True: - assert centered, "centered must be True if shift_center is True" - if test_config: - for x,y in zip(['centered','calibrated','shift_center'], - [centered,calibrated,shift_center]): - print(f"{x} = {y}") - - # Get geometry - g = get_calibrated_geometry( - datacube, - mode, - geometry, - centered, - calibrated - ) - - # Get mask - mask = make_detector(datacube.Qshape, mode, g) - # if return_mask is True, skip computation - if return_mask == True and shift_center == False: - return mask - - - # Calculate images - - # no center shifting - if shift_center == False: - # dask - if dask == True: - - # set up a generalized universal function for dask distribution - def _apply_mask_dask(datacube,mask): - virtual_image = np.sum(np.multiply(datacube.data,mask), dtype=np.float64) - apply_mask_dask = da.as_gufunc( - _apply_mask_dask,signature='(i,j),(i,j)->()', - output_dtypes=np.float64, - axes=[(2,3),(0,1),()], - vectorize=True - ) - - # compute - virtual_image = apply_mask_dask(datacube.data, mask) - - # non-dask - else: - - # compute - if mask.dtype == 'complex': - virtual_image = np.zeros(datacube.Rshape, dtype = 'complex') - else: - virtual_image = np.zeros(datacube.Rshape) - for rx,ry in tqdmnd( - datacube.R_Nx, - datacube.R_Ny, - disable = not verbose, - ): - virtual_image[rx,ry] = np.sum(datacube.data[rx,ry]*mask) - - # with center shifting - else: - - # get shifts - assert datacube.calibration.get_origin_shift(), "origin need to be calibrated" - qx_shift,qy_shift = datacube.calibration.get_origin_shift() - qx_shift = qx_shift.round().astype(int) - qy_shift = qy_shift.round().astype(int) - - # if return_mask is True, skip computation - if return_mask is not False: - try: - rx,ry = return_mask - except TypeError: - raise Exception("when `shift_center` is True, return_mask must be a 2-tuple of ints or False") - # get shifted mask - _mask = np.roll( - mask, - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1) - ) - return _mask - - # compute - if mask.dtype == 'complex': - virtual_image = np.zeros(datacube.Rshape, dtype = 'complex') - else: - virtual_image = np.zeros(datacube.Rshape) - - for rx,ry in tqdmnd( - datacube.R_Nx, - datacube.R_Ny, - disable = not verbose, - ): - # get shifted mask - _mask = np.roll( - mask, - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1) - ) - virtual_image[rx,ry] = np.sum(datacube.data[rx,ry]*_mask) - - return virtual_image - - -def get_calibrated_geometry( - calibration, - mode, - geometry, - centered, - calibrated - ): - """ - Determine the detector geometry in pixels, given some mode and geometry - in calibrated units, where the calibration state is specified by { - centered, calibrated} - - Args: - calibration (Calibration, DataCube, any object with a .calibration attr, - or None) Used to retrieve the center positions. If `None`, confirms that - centered and calibrated are False then passes - mode: see py4DSTEM.process.virtualimage.get_virtual_image - geometry: see py4DSTEM.process.virtualimage.get_virtual_image - centered: see py4DSTEM.process.virtualimage.get_virtual_image - calibrated: see py4DSTEM.process.virtualimage.get_virtual_image - - Returns: - (tuple) the geometry in detector pixels - """ - # Parse inputs - g = geometry - if calibration is None: - assert calibrated is False and centered is False - return g - elif isinstance(calibration, Calibration): - cal = calibration - else: - try: - cal = calibration.calibration - assert isinstance(cal, Calibration), "`calibration.calibration` must be a Calibration instance" - except AttributeError: - raise Exception("`calibration` must either be a Calibration instance or have a .calibration attribute") - - # Get calibration metadata - if centered: - assert cal.get_qx0_mean(), "origin needs to be calibrated" - x0_mean, y0_mean = cal.get_origin_mean() - - if calibrated: - assert cal['Q_pixel_units'] == 'A^-1', \ - 'check calibration - must be calibrated in A^-1 to use `calibrated=True`' - unit_conversion = cal.get_Q_pixel_size() - - - # Convert units into detector pixels - - # Shift center - if centered == True: - if mode == 'point': - g = (g[0] + x0_mean, g[1] + y0_mean) - if mode in('circle', 'circular', 'annulus', 'annular'): - g = ((g[0][0] + x0_mean, g[0][1] + y0_mean), g[1]) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0] + x0_mean, g[1] + x0_mean, g[2] + y0_mean, g[3] + y0_mean) - - # Scale by the detector pixel size - if calibrated == True: - if mode == 'point': - g = (g[0]/unit_conversion, g[1]/unit_conversion) - if mode in('circle', 'circular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1]/unit_conversion)) - if mode in('annulus', 'annular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1][0]/unit_conversion, g[1][1]/unit_conversion)) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0]/unit_conversion, g[1]/unit_conversion, - g[2]/unit_conversion, g[3]/unit_conversion) - - return g - - - -def make_detector( - shape, - mode, - geometry, -): - ''' - Function to return 2D mask - - Args: - shape (tuple) : defines shape of mask, for example (Q_Nx, Q_Ny) where Q_Nx and Q_Ny are mask sizes - mode (str) : defines geometry mode for calculating virtual image - options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - - 'rectangle', 'square', 'rectangular', uses rectangular detector - - 'mask' flexible detector, any boolean or floating point 2D array with - the same shape as datacube.Qshape or datacube.Rshape for virtual image - or diffraction image respectively - geometry (variable) : valid entries are determined by the `mode`, values in pixels - argument, as follows: - - 'point': 2-tuple, (qx,qy), - qx and qy are each single float or int to define center - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - 'rectangle', 'square', 'rectangular': 4-tuple, (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point 2D array with the - same shape as datacube.Qshape or datacube.Rshapefor virtual image - or diffraction image respectively - - Returns: - virtual detector in the form of a 2D mask (array) - ''' - g = geometry - - #point mask - if mode == 'point': - assert(isinstance(g,tuple) and len(g)==2), 'specify qx and qy as tuple (qx, qy)' - mask = np.zeros(shape, dtype=bool) - - qx = int(g[0]) - qy = int(g[1]) - - mask[qx,qy] = 1 - - #circular mask - if mode in('circle', 'circular'): - assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and isinstance(g[1],(float,int))), \ - 'specify qx, qy, radius_i as ((qx, qy), radius)' - - qxa, qya = np.indices(shape) - mask = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1] ** 2 - - #annular mask - if mode in('annulus', 'annular'): - assert(isinstance(g,tuple) and len(g)==2 and len(g[0])==2 and len(g[1])==2), \ - 'specify qx, qy, radius_i, radius_0 as ((qx, qy), (radius_i, radius_o))' - - assert g[1][1] > g[1][0], "Inner radius must be smaller than outer radius" - - qxa, qya = np.indices(shape) - mask1 = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 > g[1][0] ** 2 - mask2 = (qxa - g[0][0]) ** 2 + (qya - g[0][1]) ** 2 < g[1][1] ** 2 - mask = np.logical_and(mask1, mask2) - - #rectangle mask - if mode in('rectangle', 'square', 'rectangular') : - assert(isinstance(g,tuple) and len(g)==4), \ - 'specify x_min, x_max, y_min, y_max as (x_min, x_max, y_min, y_max)' - mask = np.zeros(shape, dtype=bool) - - xmin = int(np.round(g[0])) - xmax = int(np.round(g[1])) - ymin = int(np.round(g[2])) - ymax = int(np.round(g[3])) - - mask[xmin:xmax, ymin:ymax] = 1 - - #flexible mask - if mode == 'mask': - assert type(g) == np.ndarray, '`geometry` type should be `np.ndarray`' - assert (g.shape == shape), 'mask and diffraction pattern shapes do not match' - mask = g - return mask - -def make_bragg_mask( - Qshape, - g1, - g2, - radius, - origin, - max_q, - return_sum = True, - **kwargs, - ): - ''' - Creates and returns a mask consisting of circular disks - about the points of a 2D lattice. - - Args: - Qshape (2 tuple): the shape of diffraction space - g1,g2 (len 2 array or tuple): the lattice vectors - radius (number): the disk radius - origin (len 2 array or tuple): the origin - max_q (nuumber): the maxima distance to tile to - return_sum (bool): if False, return a 3D array, where each - slice contains a single disk; if False, return a single - 2D masks of all disks - - Returns: - (2 or 3D array) the mask - ''' - nas = np.asarray - g1,g2,origin = nas(g1),nas(g2),nas(origin) - - # Get N,M, the maximum indices to tile out to - L1 = np.sqrt(np.sum(g1**2)) - H = int(max_q/L1) + 1 - L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) - K = int(max_q/L2) + 1 - - # Compute number of points - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - N += 1 - - #create mask - mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - center = origin + v - mask[:,:,N] = make_detector( - Qshape, - mode = 'circle', - geometry = (center, radius), - ) - N += 1 - - - if return_sum: - mask = np.sum(mask, axis = 2) - return mask - - - - - - - - - - - - - -def get_virtual_image_pointlistarray( - peaks, - mode = None, - geometry = None, - ): - """ - Make a virtual image from a pointlist array. - TODO - implement more virtual detectors. - - Args: - peaks (PointListArray): List of all peaks and intensities. - mode (str) : defines geometry mode for calculating virtual image. - Options: - - 'circular' or 'circle' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - geometry (variable) : valid entries are determined by the `mode`, values in pixels - argument, as follows: - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) - - Returns: - im_virtual (2D numpy array): the calculated virtual image - """ - - # Set geometry - if mode is None: - if geometry is None: - center = None - radial_range = np.array((0,np.inf)) - else: - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - if isinstance(geometry[1], int) or isinstance(geometry[1], float): - radial_range = np.array((0,geometry[1])) - elif len(geometry[1]) == 0: - radial_range = None - else: - radial_range = np.array(geometry[1]) - elif mode == 'circular' or mode == 'circle': - radial_range = np.array((0,geometry[1])) - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - elif mode == 'annular' or mode == 'annulus': - radial_range = np.array(geometry[1]) - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - - - - # init - im_virtual = np.zeros(peaks.shape) - - # Generate image - for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): - p = peaks.get_pointlist(rx,ry) - if p.data.shape[0] > 0: - if radial_range is None: - im_virtual[rx,ry] = np.sum(p.data['intensity']) - else: - if center is None: - qr = np.hypot(p.data['qx'],p.data['qy']) - else: - qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) - sub = np.logical_and( - qr >= radial_range[0], - qr < radial_range[1]) - if np.sum(sub) > 0: - im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) - - return im_virtual - - -def get_virtual_image_braggvectors( - bragg_peaks, - mode = None, - geometry = None, - ): - ''' - Function to calculate virtual images from braggvectors / pointlist arrays. - TODO - implement these detectors for braggvectors - - Args: - bragg_peaks (BraggVectors) : BraggVectors class object which stores bragg peaks - mode (str) : defines geometry mode for calculating virtual image. - Options: - - 'circular' or 'circle' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - geometry (variable) : valid entries are determined by the `mode`, values in pixels - argument, as follows: - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) - - Returns: - im_virtual (2D numpy array): the calculated virtual image - ''' - - virtual_image = get_virtual_image_pointlistarray( - bragg_peaks.vectors, - mode = mode, - geometry = geometry, - ) - - return virtual_image diff --git a/py4DSTEM/visualize/__init__.py b/py4DSTEM/visualize/__init__.py index 40fdedca6..d5c183ab5 100644 --- a/py4DSTEM/visualize/__init__.py +++ b/py4DSTEM/visualize/__init__.py @@ -3,5 +3,4 @@ from py4DSTEM.visualize.vis_RQ import * from py4DSTEM.visualize.vis_grid import * from py4DSTEM.visualize.vis_special import * -from py4DSTEM.visualize.virtualimage import * diff --git a/py4DSTEM/visualize/virtualimage.py b/py4DSTEM/visualize/virtualimage.py deleted file mode 100644 index 830fde5c5..000000000 --- a/py4DSTEM/visualize/virtualimage.py +++ /dev/null @@ -1,129 +0,0 @@ -import numpy as np - -from py4DSTEM.data import Calibration, DataCube, DiffractionSlice -from py4DSTEM.visualize.show import show - - -def position_detector( - data, - mode, - geometry, - centered, - calibrated, - shift_center, - invert = False, - color = 'r', - alpha = 0.7, - **kwargs -): - """ - Display a diffraction space image with an overlaid mask representing - a virtual detector. - - Args: - data (DataCube, DiffractionSlice, array, tuple): - behavoir depends on the argument type: - DataCube - check to see if this datacube has a mean, max, - or median diffraction pattern, and if found, uses it - (order of preference as written here). If not found, - raises an exception. - DiffractionSlice - use the first slice - array - use this array. This mode only works when - centered, calibrated, and shift_center are False. - Otherwise, use the tuple entry (array, Calibration) - tuple - must be either: - - (DataCube, rx, ry) for rx,ry integers. - Use the diffraction pattern at this scan position. - `shift_center` is auto set to True in this mode. - - (array, Calibration) - mode: see py4DSTEM.process.get_virtual_image - geometry: see py4DSTEM.process.get_virtual_image - centered: see py4DSTEM.process.get_virtual_image - calibrated: see py4DSTEM.process.get_virtual_image - shift_center: see py4DSTEM.process.get_virtual_image; if True, `data` - should be a 3-tuple (DataCube, rx, ry) - invert: if True, invert the mask - **kwargs: all additional arguments are passed on to `show` - """ - # Parse data - if isinstance(data, DataCube): - cal = data.calibration - keys = ['dp_mean','dp_max','dp_median'] - for k in keys: - try: - image = data.tree(k) - break - except: - pass - else: - raise Exception("No mean, max, or median diffraction image found; try calling datacube.get_mean_dp() first") - elif isinstance(data, DiffractionSlice): - cal = data.calibration - try: - image = data[:,:,0] - except IndexError: - image = data[:,:] - elif isinstance(data, np.ndarray): - er = "centered and calibrated must be False to pass an uncalibrated array; set these to False or try using `data = (array, Calibration)`" - assert all([x is False for x in [centered,calibrated]]), er - image = data - cal = None - elif isinstance(data, tuple): - if len(data)==2: - image,cal = data - assert isinstance(image, np.ndarray) - assert isinstance(cal, Calibration) - elif len(data)==3: - data,rx,ry = data - image = data[rx,ry,:,:] - cal = data.calibration - else: - raise Exception(f"Invalid entry {data} for argument `data`") - - - # Get geometry - from py4DSTEM.process.virtualimage import get_calibrated_geometry - g = get_calibrated_geometry( - calibration = cal, - mode = mode, - geometry = geometry, - centered = centered, - calibrated = calibrated - ) - - # Get mask - from py4DSTEM.process.virtualimage import make_detector - mask = make_detector(image.shape, mode, g) - if not(invert): - mask = np.logical_not(mask) - - # Shift center - if shift_center: - try: - rx,ry - except NameError: - raise Exception("if `shift_center` is True then `data` must be the 3-tuple (DataCube,rx,ry)") - # get shifts - assert cal.get_origin_shift(), "origin shifts need to be calibrated" - qx_shift,qy_shift = cal.get_origin_shift() - qx_shift = int(np.round(qx_shift[rx,ry])) - qy_shift = int(np.round(qy_shift[rx,ry])) - mask = np.roll( - mask, - (qx_shift, qy_shift), - axis=(0,1) - ) - - # Display - - show( - image, - mask = mask, - mask_color = color, - mask_alpha = alpha, - **kwargs - ) - - return - - diff --git a/py4DSTEM/visualize/vis_RQ.py b/py4DSTEM/visualize/vis_RQ.py index 4e6f1d20a..72c50a396 100644 --- a/py4DSTEM/visualize/vis_RQ.py +++ b/py4DSTEM/visualize/vis_RQ.py @@ -3,7 +3,6 @@ from matplotlib.axes import Axes from py4DSTEM.visualize.show import show,show_points -from py4DSTEM.process.calibration.rotation import get_Qvector_from_Rvector,get_Rvector_from_Qvector @@ -79,6 +78,7 @@ def ax_addvector_RtoQ(ax,vx,vy,vlength,x0,y0,QR_rotation,width=1,color='r'): the counterclockwise rotation of real space with respect to diffraction space. In degrees. """ + from py4DSTEM.process.calibration.rotation import get_Qvector_from_Rvector _,_,vx,vy = get_Qvector_from_Rvector(vx,vy,QR_rotation) vx,vy = vx*vlength,vy*vlength ax.arrow(y0,x0,vy,vx,color=color,width=width,length_includes_head=True) @@ -102,6 +102,7 @@ def ax_addvector_QtoR(ax,vx,vy,vlength,x0,y0,QR_rotation,width=1,color='r'): the counterclockwise rotation of real space with respect to diffraction space. In degrees. """ + from py4DSTEM.process.calibration.rotation import get_Rvector_from_Qvector vx,vy,_,_ = get_Rvector_from_Qvector(vx,vy,QR_rotation) vx,vy = vx*vlength,vy*vlength ax.arrow(y0,x0,vy,vx,color=color,width=width,length_includes_head=True) @@ -278,6 +279,7 @@ def ax_addaxes_QtoR(ax,vx,vy,vlength,x0,y0,QR_rotation,width=1,color='r', the counterclockwise rotation of real space with respect to diffraction space. In degrees. """ + from py4DSTEM.process.calibration.rotation import get_Rvector_from_Qvector vx,vy,_,_ = get_Rvector_from_Qvector(vx,vy,QR_rotation) ax_addaxes(ax,vx,vy,vlength,x0,y0,width=width,color=color,labelaxes=labelaxes, labelsize=labelsize,labelcolor=labelcolor,righthandedcoords=True) @@ -304,6 +306,7 @@ def ax_addaxes_RtoQ(ax,vx,vy,vlength,x0,y0,QR_rotation,width=1,color='r', the counterclockwise rotation of real space with respect to diffraction space. In degrees. """ + from py4DSTEM.process.calibration.rotation import get_Qvector_from_Rvector _,_,vx,vy = get_Qvector_from_Rvector(vx,vy,QR_rotation) ax_addaxes(ax,vx,vy,vlength,x0,y0,width=width,color=color,labelaxes=labelaxes, labelsize=labelsize,labelcolor=labelcolor,righthandedcoords=True) diff --git a/py4DSTEM/visualize/vis_special.py b/py4DSTEM/visualize/vis_special.py index d6ce64cf5..b487048e2 100644 --- a/py4DSTEM/visualize/vis_special.py +++ b/py4DSTEM/visualize/vis_special.py @@ -6,10 +6,6 @@ from scipy.spatial import Voronoi from emdfile import PointList -from py4DSTEM.data import DataCube,Calibration -from py4DSTEM.process.utils import get_voronoi_vertices,convert_ellipse_params -from py4DSTEM.process.calibration import double_sided_gaussian -from py4DSTEM.process.latticevectors import get_selected_lattice_vectors from py4DSTEM.visualize import show from py4DSTEM.visualize.overlay import ( add_pointlabels, @@ -24,6 +20,8 @@ + + def show_elliptical_fit(ar,fitradii,p_ellipse,fill=True, color_ann='y',color_ell='r',alpha_ann=0.2,alpha_ell=0.7, linewidth_ann=2,linewidth_ell=2,returnfig=False,**kwargs): @@ -93,6 +91,8 @@ def show_amorphous_ring_fit(dp,fitradii,p_dsg,N=12,cmap=('gray','gray'), ellipse (bool): if True, overlay an ellipse returnfig (bool): if True, returns the figure """ + from py4DSTEM.process.calibration import double_sided_gaussian + from py4DSTEM.process.utils import convert_ellipse_params assert(len(p_dsg)==11) assert(isinstance(N,(int,np.integer))) if isinstance(cmap,tuple): @@ -258,6 +258,7 @@ def show_voronoi(ar,x,y,color_points='r',color_lines='w',max_dist=None, """ words """ + from py4DSTEM.process.utils import get_voronoi_vertices Nx,Ny = ar.shape points = np.vstack((x,y)).T voronoi = Voronoi(points) @@ -604,6 +605,8 @@ def select_lattice_vectors(ar,gx,gy,i0,i1,i2, if returnfig==False: g1,g2 if returnfig==True g1,g2,fig,ax """ + from py4DSTEM.process.latticevectors import get_selected_lattice_vectors + # Make the figure fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) show(ar,figax=(fig,ax1),**kwargs) @@ -702,6 +705,8 @@ def show_origin_meas(data): Args: data (DataCube or Calibration or 2-tuple of arrays (qx0,qy0)) """ + from py4DSTEM.data import Calibration + from py4DSTEM.datacube import DataCube if isinstance(data,tuple): assert len(data)==2 qx,qy = data @@ -722,6 +727,8 @@ def show_origin_fit(data): data (DataCube or Calibration or (3,2)-tuple of arrays ((qx0_meas,qy0_meas),(qx0_fit,qy0_fit),(qx0_residuals,qy0_residuals)) """ + from py4DSTEM.data import Calibration + from py4DSTEM.datacube import DataCube if isinstance(data,tuple): assert len(data)==3 qx0_meas,qy_meas = data[0] @@ -764,6 +771,7 @@ def show_selected_dps(datacube,positions,im,bragg_pos=None, **kwargs (dict): arguments passed to visualize.show for the *diffraction patterns*. Default is `scaling='log'` """ + from py4DSTEM.datacube import DataCube assert isinstance(datacube,DataCube) N = len(positions) assert(all([len(x)==2 for x in positions])), "Improperly formated argument `positions`" diff --git a/test/test_native_io/test_single_object_io.py b/test/test_native_io/test_single_object_io.py index 6687274c5..d1a826c5f 100644 --- a/test/test_native_io/test_single_object_io.py +++ b/test/test_native_io/test_single_object_io.py @@ -7,15 +7,17 @@ from py4DSTEM import save,read import emdfile as emd -from py4DSTEM.data import ( - DataCube, +from py4DSTEM import ( Calibration, DiffractionSlice, RealSlice, QPoints, + DataCube, + VirtualImage, + VirtualDiffraction, + BraggVectors, + Probe ) -from py4DSTEM.process.diskdetection import BraggVectors,Probe -from py4DSTEM.classes import VirtualDiffraction, VirtualImage # Set paths dirpath = py4DSTEM._TESTPATH From 8b5e39e846c60dfc5ea89186cfc3b84a34770c99 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Fri, 7 Jul 2023 01:04:25 -0400 Subject: [PATCH 129/362] updates --- py4DSTEM/__init__.py | 69 ++++++++--- py4DSTEM/braggvectors/__init__.py | 9 ++ .../braggvector_methods.py | 115 +++++++++++++++++- .../braggvectors.py | 2 +- .../diskdetection.py | 12 +- .../diskdetection_aiml.py | 8 +- .../diskdetection_aiml_cuda.py | 10 +- .../diskdetection_cuda.py | 2 +- .../diskdetection_parallel.py | 0 .../diskdetection_parallel_new.py | 2 +- .../diskdetection => braggvectors}/kernels.py | 0 .../multicorr_col_kernel.cu | 0 .../multicorr_row_kernel.cu | 0 .../diskdetection => braggvectors}/probe.py | 0 .../probe_gen_methods.py | 2 +- .../threshold.py | 0 py4DSTEM/braggvectors/virtualimage.py | 77 ++++++++++++ py4DSTEM/datacube/datacube.py | 4 +- py4DSTEM/datacube/virtualimage.py | 21 ++-- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 3 +- py4DSTEM/process/__init__.py | 1 - py4DSTEM/process/calibration/probe.py | 2 +- py4DSTEM/process/diskdetection/__init__.py | 9 -- test/test_braggvectors.py | 2 +- 24 files changed, 282 insertions(+), 68 deletions(-) create mode 100644 py4DSTEM/braggvectors/__init__.py rename py4DSTEM/{process/diskdetection => braggvectors}/braggvector_methods.py (87%) rename py4DSTEM/{process/diskdetection => braggvectors}/braggvectors.py (99%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection.py (98%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection_aiml.py (99%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection_aiml_cuda.py (98%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection_cuda.py (99%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection_parallel.py (100%) rename py4DSTEM/{process/diskdetection => braggvectors}/diskdetection_parallel_new.py (99%) rename py4DSTEM/{process/diskdetection => braggvectors}/kernels.py (100%) rename py4DSTEM/{process/diskdetection => braggvectors}/multicorr_col_kernel.cu (100%) rename py4DSTEM/{process/diskdetection => braggvectors}/multicorr_row_kernel.cu (100%) rename py4DSTEM/{process/diskdetection => braggvectors}/probe.py (100%) rename py4DSTEM/{process/diskdetection => braggvectors}/probe_gen_methods.py (99%) rename py4DSTEM/{process/diskdetection => braggvectors}/threshold.py (100%) create mode 100644 py4DSTEM/braggvectors/virtualimage.py delete mode 100644 py4DSTEM/process/diskdetection/__init__.py diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index ba086dc27..bf1b0554d 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -2,7 +2,9 @@ from emdfile import tqdmnd -# io classes +### io + +# substructure from emdfile import ( Node, Root, @@ -10,10 +12,20 @@ Array, PointList, PointListArray, - Custom + Custom, + print_h5_tree, ) +_emd_hook = True + +# structure +from py4DSTEM import io +from py4DSTEM.io import import_file,read,save -# processing classes + + +### basic data classes + +# data from py4DSTEM.data import ( Data, Calibration, @@ -21,47 +33,64 @@ RealSlice, QPoints, ) + +# datacube from py4DSTEM.datacube import ( DataCube, VirtualImage ) -from py4DSTEM.classes import ( - VirtualDiffraction, -) -from py4DSTEM.process.diskdetection import ( + + + +### visualization + +from py4DSTEM import visualize +from py4DSTEM.visualize import show + + + +### analysis classes + +# braggvectors +from py4DSTEM.braggvectors import ( Probe, BraggVectors, BraggVectorMap, ) + +# TODO - crystal +# TODO - ptycho +# TODO - others? + +# TODO - where? from py4DSTEM.process import ( PolarDatacube, ) +# TODO - to datacube +from py4DSTEM.classes import ( + VirtualDiffraction, +) + -# submodules -from py4DSTEM import io +### more submodules +# TODO + from py4DSTEM import preprocess from py4DSTEM import process -from py4DSTEM import classes -from py4DSTEM import visualize +### utilities -# functions -from emdfile import print_h5_tree -from py4DSTEM.visualize import show -from py4DSTEM.io import import_file,read,save +# config from py4DSTEM.utils.configuration_checker import check_config +# TODO - config .toml - -# test paths +# testing from os.path import dirname,join _TESTPATH = join(dirname(__file__), "../test/unit_test_data") -# hook for emd _get_class -_emd_hook = True - diff --git a/py4DSTEM/braggvectors/__init__.py b/py4DSTEM/braggvectors/__init__.py new file mode 100644 index 000000000..ed09c04fc --- /dev/null +++ b/py4DSTEM/braggvectors/__init__.py @@ -0,0 +1,9 @@ +from py4DSTEM.braggvectors.probe import Probe +from py4DSTEM.braggvectors.braggvectors import BraggVectors +from py4DSTEM.braggvectors.braggvector_methods import BraggVectorMap +from py4DSTEM.braggvectors.diskdetection import * +from py4DSTEM.braggvectors.probe import * +from py4DSTEM.braggvectors.probe_gen_methods import * +#from .diskdetection_aiml import * +#from .diskdetection_parallel_new import * + diff --git a/py4DSTEM/process/diskdetection/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py similarity index 87% rename from py4DSTEM/process/diskdetection/braggvector_methods.py rename to py4DSTEM/braggvectors/braggvector_methods.py index d55332214..48dbbb17f 100644 --- a/py4DSTEM/process/diskdetection/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -22,7 +22,8 @@ def histogram( weights_thresh = 0.005, ): """ - Returns a 2D histogram of Bragg vector intensities in diffraction space. + Returns a 2D histogram of Bragg vector intensities in diffraction space, + aka a Bragg vector map. Parameters ---------- @@ -176,6 +177,118 @@ def histogram( + # bragg virtual imaging + + def get_virtual_image( + self, + mode = None, + geometry = None, + returncalc = True + ): + ''' + Calculates a virtual image based on the values of the Braggvectors + integrated over some detector function determined by `mode` and + `geometry`. + + Parameters + ---------- + mode : str + defines the type of detector used. Options: + - 'circular', 'circle': uses round detector, like bright field + - 'annular', 'annulus': uses annular detector, like dark field + geometry : variable + expected value depends on the value of `mode`, as follows: + - 'circle', 'circular': nested 2-tuple, ((qx,qy),radius) + - 'annular' or 'annulus': nested 2-tuple, + ((qx,qy),(radius_i,radius_o)) + All values are in pixels. Note that (qx,qy) can be skipped, which + assumes peaks centered at (0,0) + + Returns + ------- + virtual_im : VirtualImage + ''' + # parse inputs + circle_modes = ['circular','circle'] + annulus_modes = ['annular','annulus'] + modes = circle_modes + annulus_modes + [None] + assert(mode in modes), f"Unrecognized mode {mode}" + + # set geometry +# if mode is None: +# if geometry is None: +# center = None +# radial_range = np.array((0,np.inf)) +# else: +# if len(geometry[0]) == 0: +# center = None +# else: +# center = np.array(geometry[0]) +# if isinstance(geometry[1], int) or isinstance(geometry[1], float): +# radial_range = np.array((0,geometry[1])) +# elif len(geometry[1]) == 0: +# radial_range = None +# else: +# radial_range = np.array(geometry[1]) +# elif mode == 'circular' or mode == 'circle': +# radial_range = np.array((0,geometry[1])) +# if len(geometry[0]) == 0: +# center = None +# else: +# center = np.array(geometry[0]) +# elif mode == 'annular' or mode == 'annulus': +# radial_range = np.array(geometry[1]) +# if len(geometry[0]) == 0: +# center = None +# else: +# center = np.array(geometry[0]) + + + + # allocate space + im_virtual = np.zeros(peaks.shape) + + # generate image + for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): + p = peaks.get_pointlist(rx,ry) + if p.data.shape[0] > 0: + if radial_range is None: + im_virtual[rx,ry] = np.sum(p.data['intensity']) + else: + if center is None: + qr = np.hypot(p.data['qx'],p.data['qy']) + else: + qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) + sub = np.logical_and( + qr >= radial_range[0], + qr < radial_range[1]) + if np.sum(sub) > 0: + im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) + +# # generate image +# for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): +# p = peaks.get_pointlist(rx,ry) +# if p.data.shape[0] > 0: +# if radial_range is None: +# im_virtual[rx,ry] = np.sum(p.data['intensity']) +# else: +# if center is None: +# qr = np.hypot(p.data['qx'],p.data['qy']) +# else: +# qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) +# sub = np.logical_and( +# qr >= radial_range[0], +# qr < radial_range[1]) +# if np.sum(sub) > 0: +# im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) + + # TODO wrap in VirtualImage + + return im_virtual + + + + # calibration measurements def measure_origin( diff --git a/py4DSTEM/process/diskdetection/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py similarity index 99% rename from py4DSTEM/process/diskdetection/braggvectors.py rename to py4DSTEM/braggvectors/braggvectors.py index 1b84dc8b6..ebd5e7389 100644 --- a/py4DSTEM/process/diskdetection/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -2,7 +2,7 @@ from py4DSTEM.data import Data from emdfile import Custom,PointListArray,PointList,Metadata -from py4DSTEM.process.diskdetection.braggvector_methods import BraggVectorMethods +from py4DSTEM.braggvectors.braggvector_methods import BraggVectorMethods from os.path import basename import numpy as np from warnings import warn diff --git a/py4DSTEM/process/diskdetection/diskdetection.py b/py4DSTEM/braggvectors/diskdetection.py similarity index 98% rename from py4DSTEM/process/diskdetection/diskdetection.py rename to py4DSTEM/braggvectors/diskdetection.py index 077b267f7..fb7755349 100644 --- a/py4DSTEM/process/diskdetection/diskdetection.py +++ b/py4DSTEM/braggvectors/diskdetection.py @@ -5,12 +5,12 @@ from scipy.ndimage import gaussian_filter from emdfile import tqdmnd -from py4DSTEM.process.diskdetection.braggvectors import BraggVectors +from py4DSTEM.braggvectors.braggvectors import BraggVectors from py4DSTEM.data import QPoints from py4DSTEM.datacube import DataCube from py4DSTEM.preprocess.utils import get_maxima_2D from py4DSTEM.process.utils.cross_correlate import get_cross_correlation_FT -from py4DSTEM.process.diskdetection.diskdetection_aiml import find_Bragg_disks_aiml +from py4DSTEM.braggvectors.diskdetection_aiml import find_Bragg_disks_aiml @@ -573,7 +573,7 @@ def _find_Bragg_disks_CUDA_unbatched( ): # compute - from py4DSTEM.process.diskdetection.diskdetection_cuda import find_Bragg_disks_CUDA + from py4DSTEM.braggvectors.diskdetection_cuda import find_Bragg_disks_CUDA peaks = find_Bragg_disks_CUDA( datacube, probe, @@ -619,7 +619,7 @@ def _find_Bragg_disks_CUDA_batched( ): # compute - from py4DSTEM.process.diskdetection.diskdetection_cuda import find_Bragg_disks_CUDA + from py4DSTEM.braggvectors.diskdetection_cuda import find_Bragg_disks_CUDA peaks = find_Bragg_disks_CUDA( datacube, probe, @@ -669,7 +669,7 @@ def _find_Bragg_disks_ipp( ): # compute - from py4DSTEM.process.diskdetection.diskdetection_parallel import find_Bragg_disks_ipp + from py4DSTEM.braggvectors.diskdetection_parallel import find_Bragg_disks_ipp peaks = find_Bragg_disks_ipp( datacube, probe, @@ -721,7 +721,7 @@ def _find_Bragg_disks_dask( ): # compute - from py4DSTEM.process.diskdetection.diskdetection_parallel import find_Bragg_disks_dask + from py4DSTEM.braggvectors.diskdetection_parallel import find_Bragg_disks_dask peaks = find_Bragg_disks_dask( datacube, probe, diff --git a/py4DSTEM/process/diskdetection/diskdetection_aiml.py b/py4DSTEM/braggvectors/diskdetection_aiml.py similarity index 99% rename from py4DSTEM/process/diskdetection/diskdetection_aiml.py rename to py4DSTEM/braggvectors/diskdetection_aiml.py index 8f82dce9a..6d9bea623 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_aiml.py +++ b/py4DSTEM/braggvectors/diskdetection_aiml.py @@ -14,10 +14,10 @@ from numbers import Number from emdfile import tqdmnd, PointList, PointListArray -from py4DSTEM.process.diskdetection.braggvectors import BraggVectors +from py4DSTEM.braggvectors.braggvectors import BraggVectors from py4DSTEM.data import QPoints from py4DSTEM.process.utils import get_maxima_2D -# from py4DSTEM.process.diskdetection import universal_threshold +# from py4DSTEM.braggvectors import universal_threshold def find_Bragg_disks_aiml_single_DP(DP, probe, num_attempts = 5, @@ -430,7 +430,7 @@ def find_Bragg_disks_aiml_serial(datacube, probe, int(t2/60), int(t2%60))) if global_threshold == True: - from py4DSTEM.process.diskdetection import universal_threshold + from py4DSTEM.braggvectors import universal_threshold peaks = universal_threshold(peaks, minGlobalIntensity, metric, minPeakSpacing, maxNumPeaks) @@ -624,7 +624,7 @@ def _parse_distributed(distributed): name=name, filter_function=filter_function) elif _check_cuda_device_available(): - from py4DSTEM.process.diskdetection.diskdetection_aiml_cuda import find_Bragg_disks_aiml_CUDA + from py4DSTEM.braggvectors.diskdetection_aiml_cuda import find_Bragg_disks_aiml_CUDA return find_Bragg_disks_aiml_CUDA(datacube, probe, num_attempts = num_attempts, diff --git a/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py b/py4DSTEM/braggvectors/diskdetection_aiml_cuda.py similarity index 98% rename from py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py rename to py4DSTEM/braggvectors/diskdetection_aiml_cuda.py index fbc9339a0..d714feda9 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_aiml_cuda.py +++ b/py4DSTEM/braggvectors/diskdetection_aiml_cuda.py @@ -7,12 +7,12 @@ from time import time from emdfile import tqdmnd -from py4DSTEM.process.diskdetection.braggvectors import BraggVectors +from py4DSTEM.braggvectors.braggvectors import BraggVectors from emdfile import PointList, PointListArray from py4DSTEM.data import QPoints -from py4DSTEM.process.diskdetection.kernels import kernels -from py4DSTEM.process.diskdetection.diskdetection_aiml import _get_latest_model -# from py4DSTEM.process.diskdetection.diskdetection import universal_threshold +from py4DSTEM.braggvectors.kernels import kernels +from py4DSTEM.braggvectors.diskdetection_aiml import _get_latest_model +# from py4DSTEM.braggvectors.diskdetection import universal_threshold try: import cupy as cp @@ -195,7 +195,7 @@ def find_Bragg_disks_aiml_CUDA(datacube, probe, print("Analyzed {} diffraction patterns in {}h {}m {}s".format(datacube.R_N, int(t2/3600), int(t2/60), int(t2%60))) if global_threshold == True: - from py4DSTEM.process.diskdetection import universal_threshold + from py4DSTEM.braggvectors import universal_threshold peaks = universal_threshold(peaks, minGlobalIntensity, metric, minPeakSpacing, maxNumPeaks) peaks.name = name diff --git a/py4DSTEM/process/diskdetection/diskdetection_cuda.py b/py4DSTEM/braggvectors/diskdetection_cuda.py similarity index 99% rename from py4DSTEM/process/diskdetection/diskdetection_cuda.py rename to py4DSTEM/braggvectors/diskdetection_cuda.py index df5793b47..b912bde48 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_cuda.py +++ b/py4DSTEM/braggvectors/diskdetection_cuda.py @@ -12,7 +12,7 @@ from emdfile import tqdmnd from py4DSTEM import PointList, PointListArray -from py4DSTEM.process.diskdetection.kernels import kernels +from py4DSTEM.braggvectors.kernels import kernels def find_Bragg_disks_CUDA( diff --git a/py4DSTEM/process/diskdetection/diskdetection_parallel.py b/py4DSTEM/braggvectors/diskdetection_parallel.py similarity index 100% rename from py4DSTEM/process/diskdetection/diskdetection_parallel.py rename to py4DSTEM/braggvectors/diskdetection_parallel.py diff --git a/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py b/py4DSTEM/braggvectors/diskdetection_parallel_new.py similarity index 99% rename from py4DSTEM/process/diskdetection/diskdetection_parallel_new.py rename to py4DSTEM/braggvectors/diskdetection_parallel_new.py index af011cb8e..241cae2f7 100644 --- a/py4DSTEM/process/diskdetection/diskdetection_parallel_new.py +++ b/py4DSTEM/braggvectors/diskdetection_parallel_new.py @@ -18,7 +18,7 @@ import py4DSTEM from emdfile import PointListArray, PointList -from py4DSTEM.process.diskdetection.diskdetection import _find_Bragg_disks_single_DP_FK +from py4DSTEM.braggvectors.diskdetection import _find_Bragg_disks_single_DP_FK diff --git a/py4DSTEM/process/diskdetection/kernels.py b/py4DSTEM/braggvectors/kernels.py similarity index 100% rename from py4DSTEM/process/diskdetection/kernels.py rename to py4DSTEM/braggvectors/kernels.py diff --git a/py4DSTEM/process/diskdetection/multicorr_col_kernel.cu b/py4DSTEM/braggvectors/multicorr_col_kernel.cu similarity index 100% rename from py4DSTEM/process/diskdetection/multicorr_col_kernel.cu rename to py4DSTEM/braggvectors/multicorr_col_kernel.cu diff --git a/py4DSTEM/process/diskdetection/multicorr_row_kernel.cu b/py4DSTEM/braggvectors/multicorr_row_kernel.cu similarity index 100% rename from py4DSTEM/process/diskdetection/multicorr_row_kernel.cu rename to py4DSTEM/braggvectors/multicorr_row_kernel.cu diff --git a/py4DSTEM/process/diskdetection/probe.py b/py4DSTEM/braggvectors/probe.py similarity index 100% rename from py4DSTEM/process/diskdetection/probe.py rename to py4DSTEM/braggvectors/probe.py diff --git a/py4DSTEM/process/diskdetection/probe_gen_methods.py b/py4DSTEM/braggvectors/probe_gen_methods.py similarity index 99% rename from py4DSTEM/process/diskdetection/probe_gen_methods.py rename to py4DSTEM/braggvectors/probe_gen_methods.py index e40208a11..a6afb1506 100644 --- a/py4DSTEM/process/diskdetection/probe_gen_methods.py +++ b/py4DSTEM/braggvectors/probe_gen_methods.py @@ -6,7 +6,7 @@ from emdfile import tqdmnd from py4DSTEM.datacube import DataCube -from py4DSTEM.process.diskdetection import Probe +from py4DSTEM.braggvectors import Probe from py4DSTEM.process.utils import get_shifted_ar, get_shift diff --git a/py4DSTEM/process/diskdetection/threshold.py b/py4DSTEM/braggvectors/threshold.py similarity index 100% rename from py4DSTEM/process/diskdetection/threshold.py rename to py4DSTEM/braggvectors/threshold.py diff --git a/py4DSTEM/braggvectors/virtualimage.py b/py4DSTEM/braggvectors/virtualimage.py new file mode 100644 index 000000000..0bfd9eb61 --- /dev/null +++ b/py4DSTEM/braggvectors/virtualimage.py @@ -0,0 +1,77 @@ +import numpy as np +from emdfile import tqdmnd + + + + + + +## TODO + + +def make_bragg_mask( + Qshape, + g1, + g2, + radius, + origin, + max_q, + return_sum = True, + **kwargs, + ): + ''' + Creates and returns a mask consisting of circular disks + about the points of a 2D lattice. + + Args: + Qshape (2 tuple): the shape of diffraction space + g1,g2 (len 2 array or tuple): the lattice vectors + radius (number): the disk radius + origin (len 2 array or tuple): the origin + max_q (nuumber): the maxima distance to tile to + return_sum (bool): if False, return a 3D array, where each + slice contains a single disk; if False, return a single + 2D masks of all disks + + Returns: + (2 or 3D array) the mask + ''' + nas = np.asarray + g1,g2,origin = nas(g1),nas(g2),nas(origin) + + # Get N,M, the maximum indices to tile out to + L1 = np.sqrt(np.sum(g1**2)) + H = int(max_q/L1) + 1 + L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) + K = int(max_q/L2) + 1 + + # Compute number of points + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + N += 1 + + #create mask + mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + center = origin + v + mask[:,:,N] = make_detector( + Qshape, + mode = 'circle', + geometry = (center, radius), + ) + N += 1 + + + if return_sum: + mask = np.sum(mask, axis = 2) + return mask + + + diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index d5da96fc6..55428bddc 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -1003,7 +1003,7 @@ def get_vacuum_probe( the vacuum probe """ from py4DSTEM.process.utils import get_shifted_ar, get_shift - from py4DSTEM.process.diskdetection import Probe + from py4DSTEM.braggvectors import Probe # parse region to use if ROI is None: @@ -1319,7 +1319,7 @@ def find_Bragg_disks( variable See above. """ - from py4DSTEM.process.diskdetection import find_Bragg_disks + from py4DSTEM.braggvectors import find_Bragg_disks sigma_cc = sigma if sigma is not None else sigma_cc diff --git a/py4DSTEM/datacube/virtualimage.py b/py4DSTEM/datacube/virtualimage.py index ae0b67b62..3d721431b 100644 --- a/py4DSTEM/datacube/virtualimage.py +++ b/py4DSTEM/datacube/virtualimage.py @@ -1,11 +1,8 @@ -# Methods and classes for generating virtual images - -# includes -# -------- -# VirtualImage - a container for virtual image data + metadata -# DataCubeVirtualImager - methods inherited by DataCube for virt imaging -# BraggVectorsVirtualImager - methods inherited by BraggVectors for virt imaging - +# Virtual imaging from a datacube. Includes: +# * VirtualImage - a container for virtual image data + metadata +# * DataCubeVirtualImager - methods inherited by DataCube for virt imaging +# +# for bragg virtual imaging methods, goto diskdetection.virtualimage.py import numpy as np import dask.array as da @@ -17,8 +14,7 @@ -# Virtual image class -# a container for the final virtual image data/metadata +# Virtual image container class class VirtualImage(RealSlice,Data): """ @@ -63,9 +59,7 @@ def _get_constructor_args(cls,group): -# DataCubeVirtualImage class -# inherited by DataCube, adding the methods performing -# virtual image computations +# DataCube virtual imaging methods class DataCubeVirtualImager: @@ -820,3 +814,4 @@ def get_virtual_image_braggvectors( ) return virtual_image + diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 5ac2a843a..825892fa9 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -50,7 +50,6 @@ from py4DSTEM.classes import ( VirtualDiffraction, ) -from py4DSTEM.process.diskdetection import BraggVectors, Probe @@ -179,6 +178,7 @@ def _v13_to_14_cls(obj): pass elif isinstance(obj, Probe13): + from py4DSTEM.braggvectors import Probe x = Probe( name = obj.name, data = obj.data @@ -191,6 +191,7 @@ def _v13_to_14_cls(obj): ) elif isinstance(obj, BraggVectors13): + from py4DSTEM.braggvectors import BraggVectors x = BraggVectors( name = obj.name, Rshape = obj.Rshape, diff --git a/py4DSTEM/process/__init__.py b/py4DSTEM/process/__init__.py index 510870f50..833466cd3 100644 --- a/py4DSTEM/process/__init__.py +++ b/py4DSTEM/process/__init__.py @@ -1,6 +1,5 @@ from py4DSTEM.process.polar import PolarDatacube -from py4DSTEM.process import diskdetection from py4DSTEM.process import virtualdiffraction from py4DSTEM.process import latticevectors from py4DSTEM.process import phase diff --git a/py4DSTEM/process/calibration/probe.py b/py4DSTEM/process/calibration/probe.py index 8d9a87ae2..c239590c5 100644 --- a/py4DSTEM/process/calibration/probe.py +++ b/py4DSTEM/process/calibration/probe.py @@ -34,7 +34,7 @@ def get_probe_size(DP, thresh_lower=0.01, thresh_upper=0.99, N=100): * **x0**: *(float)* the x position of the central disk center * **y0**: *(float)* the y position of the central disk center """ - from py4DSTEM.process.diskdetection import Probe + from py4DSTEM.braggvectors import Probe # parse input if isinstance(DP,Probe): diff --git a/py4DSTEM/process/diskdetection/__init__.py b/py4DSTEM/process/diskdetection/__init__.py deleted file mode 100644 index 6ea191fbd..000000000 --- a/py4DSTEM/process/diskdetection/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from py4DSTEM.process.diskdetection.probe import Probe -from py4DSTEM.process.diskdetection.braggvectors import BraggVectors -from py4DSTEM.process.diskdetection.braggvector_methods import BraggVectorMap -from py4DSTEM.process.diskdetection.diskdetection import * -from py4DSTEM.process.diskdetection.probe import * -from py4DSTEM.process.diskdetection.probe_gen_methods import * -#from .diskdetection_aiml import * -#from .diskdetection_parallel_new import * - diff --git a/test/test_braggvectors.py b/test/test_braggvectors.py index f250f7a0f..36ec138a0 100644 --- a/test/test_braggvectors.py +++ b/test/test_braggvectors.py @@ -61,7 +61,7 @@ def setup_class(cls): def test_BraggVectors_import(self): - from py4DSTEM.process.diskdetection import BraggVectors + from py4DSTEM.braggvectors import BraggVectors pass From edf163914bd3e0666423729ff7f31660aab11b47 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 08:59:18 -0700 Subject: [PATCH 130/362] ptychoptimize formatting --- py4DSTEM/process/phase/__init__.py | 1 + py4DSTEM/process/phase/parameter_optimize.py | 97 ++++++++++++-------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index 207e44b56..ee542524f 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -10,5 +10,6 @@ from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction +from py4DSTEM.process.phase.utils import OptimizationParameter, PtychographyOptimizer # fmt: on diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index f871a3a0e..da1cf3d7b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -22,7 +22,7 @@ class PtychographyOptimizer: """ Optimize ptychographic hyperparameters with Bayesian Optimization of a - Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical + Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical arguments to the ptychographic init-preprocess-reconstruct pipeline can be optimized over. """ @@ -135,7 +135,7 @@ def optimize( 'std': negative standard deviation of cropped object 'std-phase': negative standard deviation of phase of the cropped object - 'entropy-phase': entropy of the phase of the + 'entropy-phase': entropy of the phase of the cropped object When passed as a Callable, a function that takes the PhaseReconstruction object as its only argument @@ -216,49 +216,54 @@ def visualize( if ndims == 1: if plot_convergence: figsize = kwargs.pop("figsize", (9, 9)) - spec = GridSpec(nrows=2,ncols=1,height_ratios=[2,1], hspace=0.15) + spec = GridSpec(nrows=2, ncols=1, height_ratios=[2, 1], hspace=0.15) else: figsize = kwargs.pop("figsize", (9, 6)) - spec = GridSpec(nrows=1,ncols=1) + spec = GridSpec(nrows=1, ncols=1) - fig = plt.figure(figsize = figsize) + fig = plt.figure(figsize=figsize) ax = fig.add_subplot(spec[0]) - skopt_plot_gaussian_process(self._skopt_result,ax=ax, **kwargs) + skopt_plot_gaussian_process(self._skopt_result, ax=ax, **kwargs) if plot_convergence: ax = fig.add_subplot(spec[1]) - skopt_plot_convergence(self._skopt_result,ax=ax) + skopt_plot_convergence(self._skopt_result, ax=ax) else: if plot_convergence: - figsize = kwargs.pop("figsize", (4*ndims, 4*(ndims+0.5))) - spec = GridSpec(nrows=ndims+1,ncols=ndims,height_ratios=[2]*ndims+[1], hspace=0.15) + figsize = kwargs.pop("figsize", (4 * ndims, 4 * (ndims + 0.5))) + spec = GridSpec( + nrows=ndims + 1, + ncols=ndims, + height_ratios=[2] * ndims + [1], + hspace=0.15, + ) else: - figsize = kwargs.pop("figsize", (4*ndims, 4*ndims)) - spec = GridSpec(nrows=ndims,ncols=ndims, hspace=0.15) + figsize = kwargs.pop("figsize", (4 * ndims, 4 * ndims)) + spec = GridSpec(nrows=ndims, ncols=ndims, hspace=0.15) if plot_evaluations: axs = skopt_plot_evaluations(self._skopt_result) elif plot_objective: - cmap = kwargs.pop("cmap", 'magma') - axs = skopt_plot_objective(self._skopt_result, cmap=cmap,**kwargs) + cmap = kwargs.pop("cmap", "magma") + axs = skopt_plot_objective(self._skopt_result, cmap=cmap, **kwargs) elif plot_convergence: skopt_plot_convergence(self._skopt_result) return self - fig = axs[0,0].figure + fig = axs[0, 0].figure fig.set_size_inches(figsize) for i in range(ndims): for j in range(ndims): - ax = axs[i,j] + ax = axs[i, j] ax.remove() ax.figure = fig fig.add_axes(ax) - ax.set_subplotspec(spec[i,j]) + ax.set_subplotspec(spec[i, j]) if plot_convergence: - ax = fig.add_subplot(spec[ndims,:]) - skopt_plot_convergence(self._skopt_result,ax=ax) + ax = fig.add_subplot(spec[ndims, :]) + skopt_plot_convergence(self._skopt_result, ax=ax) spec.tight_layout(fig) @@ -275,14 +280,20 @@ def get_optimized_arguments(self): where the OptimizationParameter items have been replaced with the optimal values obtained from the optimizer """ - optimized_dict = {p.name: v for p,v in zip(self._parameter_list,self._skopt_result.x)} - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._init_args } + optimized_dict = { + p.name: v for p, v in zip(self._parameter_list, self._skopt_result.x) + } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._init_args + } init_opt = self._init_args | filtered_dict - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._affine_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._affine_args + } affine_opt = self._affine_args | filtered_dict - + affine_transform = partial(AffineTransform, **self._affine_static_args)( **affine_opt ) @@ -290,13 +301,17 @@ def get_optimized_arguments(self): affine_transform, init_opt["datacube"] ) init_opt["initial_scan_positions"] = scan_positions - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._preprocess_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._preprocess_args + } prep_opt = self._preprocess_args | filtered_dict - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._reconstruction_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._reconstruction_args + } reco_opt = self._reconstruction_args | filtered_dict - + return init_opt, prep_opt, reco_opt def _split_static_and_optimization_vars(self, argdict): @@ -385,10 +400,13 @@ def f(ptycho): return -np.std(np.angle(ptycho.object_cropped)) elif error_metric == "entropy-phase": + def f(ptycho): obj = np.angle(ptycho.object_cropped) - gx,gy = np.gradient(obj) - ghist,_,_ = np.histogram2d(gx.ravel(),gy.ravel(),bins=obj.shape,density=True) + gx, gy = np.gradient(obj) + ghist, _, _ = np.histogram2d( + gx.ravel(), gy.ravel(), bins=obj.shape, density=True + ) nz = ghist > 0 S = np.sum(ghist[nz] * np.log2(ghist[nz])) return S @@ -482,14 +500,14 @@ def f(**kwargs): def _set_optimizer_defaults( self, - verbose = False, - plot_center_of_mass = False, - plot_rotation = False, - plot_probe_overlaps = False, - progress_bar = False, - store_iterations = False, - reset = True, - ): + verbose=False, + plot_center_of_mass=False, + plot_rotation=False, + plot_probe_overlaps=False, + progress_bar=False, + store_iterations=False, + reset=True, + ): """ Set all of the verbose and plotting to False, allowing for user-overwrite. """ @@ -539,7 +557,6 @@ def __init__( if space not in ("real", "integer", "bool", "categorical"): raise ValueError(f"Unknown Parameter type: {space}") - scaling = scaling.lower() if scaling not in ("uniform", "log-uniform"): raise ValueError(f"Unknown scaling: {scaling}") From f653ff1cb1bebc6d1733f04f2ea9fe85f08d383e Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:00:23 -0700 Subject: [PATCH 131/362] ptychoptimize imports ordering --- py4DSTEM/process/phase/parameter_optimize.py | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index da1cf3d7b..91a71cb30 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -1,22 +1,19 @@ -from tqdm import tqdm -from skopt import gp_minimize -from skopt.space import Real, Integer, Categorical -from skopt.plots import ( - plot_convergence as skopt_plot_convergence, - plot_gaussian_process as skopt_plot_gaussian_process, - plot_evaluations as skopt_plot_evaluations, - plot_objective as skopt_plot_objective, -) -from skopt.utils import use_named_args -import matplotlib.pyplot as plt -from matplotlib.gridspec import GridSpec -import numpy as np - from functools import partial -from typing import Union, Callable +from typing import Callable, Union +import matplotlib.pyplot as plt +import numpy as np +from matplotlib.gridspec import GridSpec from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction from py4DSTEM.process.phase.utils import AffineTransform +from skopt import gp_minimize +from skopt.plots import plot_convergence as skopt_plot_convergence +from skopt.plots import plot_evaluations as skopt_plot_evaluations +from skopt.plots import plot_gaussian_process as skopt_plot_gaussian_process +from skopt.plots import plot_objective as skopt_plot_objective +from skopt.space import Categorical, Integer, Real +from skopt.utils import use_named_args +from tqdm import tqdm class PtychographyOptimizer: From 20494d11b4270b0a2ed8b434a0f51dc09bf3a8a4 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:03:57 -0700 Subject: [PATCH 132/362] init bugfix --- py4DSTEM/process/phase/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index ee542524f..cb9176375 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -10,6 +10,6 @@ from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction -from py4DSTEM.process.phase.utils import OptimizationParameter, PtychographyOptimizer +from py4DSTEM.process.phase.parameter_optimize import OptimizationParameter, PtychographyOptimizer # fmt: on From a57cfe39efab88976cdc77e18d66773f4ee82639 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:36:17 -0700 Subject: [PATCH 133/362] making generalized-projections ptychoptimize-compatible --- .../iterative_mixedstate_ptychography.py | 30 +++++++++++++---- .../iterative_multislice_ptychography.py | 32 +++++++++++++------ .../iterative_overlap_magnetic_tomography.py | 32 +++++++++++++------ .../phase/iterative_overlap_tomography.py | 32 +++++++++++++------ .../iterative_simultaneous_ptychography.py | 30 +++++++++++++---- .../iterative_singleslice_ptychography.py | 30 +++++++++++++---- 6 files changed, 138 insertions(+), 48 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 8d4574aa4..3450d1b13 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1259,6 +1259,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1303,7 +1306,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1311,6 +1314,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1390,17 +1399,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1459,7 +1474,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 36b44b77e..f9f8c2d29 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1653,6 +1653,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1703,7 +1706,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1711,8 +1714,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1804,17 +1811,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1873,7 +1886,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 7497183da..0c751cd33 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1877,6 +1877,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1923,7 +1926,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1931,8 +1934,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -2010,17 +2017,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -2079,7 +2092,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 82d1caac3..037a3c805 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1690,6 +1690,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1733,7 +1736,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1741,8 +1744,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1818,17 +1825,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1887,7 +1900,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 9e4b39cf5..629108b54 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2405,6 +2405,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -2453,7 +2456,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -2461,6 +2464,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -2549,17 +2558,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -2618,7 +2633,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 6004b2a98..4e0aaa17e 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1167,6 +1167,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1211,7 +1214,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1219,6 +1222,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1301,17 +1310,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1370,7 +1385,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " From 03549f56de34d2e8552beac84733d81dc0578cbf Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:43:38 -0700 Subject: [PATCH 134/362] centered Fourier-probe extent --- .../phase/iterative_mixedstate_ptychography.py | 16 ++++++++-------- .../phase/iterative_multislice_ptychography.py | 17 ++++++++--------- .../phase/iterative_overlap_tomography.py | 17 ++++++++--------- .../iterative_simultaneous_ptychography.py | 8 ++++---- .../phase/iterative_singleslice_ptychography.py | 16 ++++++++-------- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 3450d1b13..d4e2e5346 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1838,10 +1838,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ @@ -2075,10 +2075,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index f9f8c2d29..d477da8ce 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -2269,12 +2269,11 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] - elif plot_probe: probe_extent = [ 0, @@ -2510,10 +2509,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 037a3c805..61d40473d 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2460,12 +2460,11 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] - elif plot_probe: probe_extent = [ 0, @@ -2717,10 +2716,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 629108b54..545900634 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -3052,10 +3052,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 4e0aaa17e..bed535665 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1751,10 +1751,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ @@ -1988,10 +1988,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ From 8bffee7b618fd890a4fb7531c88e7a7a7d0e3051 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Fri, 7 Jul 2023 15:22:46 -0400 Subject: [PATCH 135/362] updates, completes rm classes/ --- py4DSTEM/__init__.py | 11 +- py4DSTEM/braggvectors/braggvector_methods.py | 119 ++--- py4DSTEM/braggvectors/braggvectors.py | 8 +- py4DSTEM/braggvectors/virtualimage.py | 77 ---- py4DSTEM/classes/__init__.py | 5 - py4DSTEM/classes/virtualdiffraction.py | 50 --- py4DSTEM/datacube/__init__.py | 1 + py4DSTEM/datacube/datacube.py | 407 +----------------- py4DSTEM/datacube/virtualdiffraction.py | 362 ++++++++++++++++ py4DSTEM/datacube/virtualimage.py | 135 +----- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 4 +- .../iterative_overlap_magnetic_tomography.py | 2 +- 12 files changed, 446 insertions(+), 735 deletions(-) delete mode 100644 py4DSTEM/braggvectors/virtualimage.py delete mode 100644 py4DSTEM/classes/__init__.py delete mode 100644 py4DSTEM/classes/virtualdiffraction.py create mode 100644 py4DSTEM/datacube/virtualdiffraction.py diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index bf1b0554d..17d255d92 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -37,7 +37,8 @@ # datacube from py4DSTEM.datacube import ( DataCube, - VirtualImage + VirtualImage, + VirtualDiffraction ) @@ -60,17 +61,13 @@ # TODO - crystal # TODO - ptycho -# TODO - others? +# TODO - others -# TODO - where? +# TODO - where from py4DSTEM.process import ( PolarDatacube, ) -# TODO - to datacube -from py4DSTEM.classes import ( - VirtualDiffraction, -) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 48dbbb17f..c6289a253 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -2,9 +2,12 @@ import numpy as np from scipy.ndimage import gaussian_filter +import inspect + from emdfile import Array,Metadata from emdfile import _read_metadata from py4DSTEM.process.utils import get_CoM +from py4DSTEM.datacube import VirtualImage class BraggVectorMethods: @@ -183,6 +186,7 @@ def get_virtual_image( self, mode = None, geometry = None, + name = 'bragg_virtual_image', returncalc = True ): ''' @@ -215,76 +219,77 @@ def get_virtual_image( assert(mode in modes), f"Unrecognized mode {mode}" # set geometry -# if mode is None: -# if geometry is None: -# center = None -# radial_range = np.array((0,np.inf)) -# else: -# if len(geometry[0]) == 0: -# center = None -# else: -# center = np.array(geometry[0]) -# if isinstance(geometry[1], int) or isinstance(geometry[1], float): -# radial_range = np.array((0,geometry[1])) -# elif len(geometry[1]) == 0: -# radial_range = None -# else: -# radial_range = np.array(geometry[1]) -# elif mode == 'circular' or mode == 'circle': -# radial_range = np.array((0,geometry[1])) -# if len(geometry[0]) == 0: -# center = None -# else: -# center = np.array(geometry[0]) -# elif mode == 'annular' or mode == 'annulus': -# radial_range = np.array(geometry[1]) -# if len(geometry[0]) == 0: -# center = None -# else: -# center = np.array(geometry[0]) - - + if mode is None: + if geometry is None: + center = None + radial_range = np.array((0,np.inf)) + else: + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) + if isinstance(geometry[1], int) or isinstance(geometry[1], float): + radial_range = np.array((0,geometry[1])) + elif len(geometry[1]) == 0: + radial_range = None + else: + radial_range = np.array(geometry[1]) + elif mode == 'circular' or mode == 'circle': + radial_range = np.array((0,geometry[1])) + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) + elif mode == 'annular' or mode == 'annulus': + radial_range = np.array(geometry[1]) + if len(geometry[0]) == 0: + center = None + else: + center = np.array(geometry[0]) # allocate space - im_virtual = np.zeros(peaks.shape) + im_virtual = np.zeros(self.shape) # generate image - for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): - p = peaks.get_pointlist(rx,ry) + for rx,ry in tqdmnd(self.shape[0],self.shape[1]): + p = self.raw[rx,ry] if p.data.shape[0] > 0: if radial_range is None: - im_virtual[rx,ry] = np.sum(p.data['intensity']) + im_virtual[rx,ry] = np.sum(p.I) else: if center is None: - qr = np.hypot(p.data['qx'],p.data['qy']) + qr = np.hypot(p.qx,p.qy) else: - qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) + qr = np.hypot(p.qx - center[0],p.qy - center[1]) sub = np.logical_and( qr >= radial_range[0], qr < radial_range[1]) if np.sum(sub) > 0: - im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) - -# # generate image -# for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): -# p = peaks.get_pointlist(rx,ry) -# if p.data.shape[0] > 0: -# if radial_range is None: -# im_virtual[rx,ry] = np.sum(p.data['intensity']) -# else: -# if center is None: -# qr = np.hypot(p.data['qx'],p.data['qy']) -# else: -# qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) -# sub = np.logical_and( -# qr >= radial_range[0], -# qr < radial_range[1]) -# if np.sum(sub) > 0: -# im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) - - # TODO wrap in VirtualImage - - return im_virtual + im_virtual[rx,ry] = np.sum(p.I[sub]) + + # wrap in Virtual Image class + ans = VirtualImage( + data = im_virtual, + name = name + ) + # add generating params as metadta + ans.metadata = Metadata( + name = 'gen_params', + data = { + '_calling_method' : inspect.stack()[0][3], + '_calling_class' : __class__.__name__, + 'mode' : mode, + 'geometry' : geometry, + 'name' : name, + 'returncalc' : returncalc + } + ) + # attach to the tree + self.attach( ans) + + # return + if returncalc: + return ans diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index ebd5e7389..d32997673 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -72,7 +72,6 @@ def __init__( Data.__init__(self,calibration=calibration) self.Rshape = Rshape - self.shape = self.Rshape self.Qshape = Qshape self.verbose = verbose @@ -102,6 +101,8 @@ def __init__( self._set_cal_vector_getter() + # calibration state, vector getters + @property def calstate(self): return self._calstate @@ -115,6 +116,10 @@ def _set_cal_vector_getter(self): ) + # shape + @property + def shape(self): + return self.Rshape # raw vectors @@ -132,7 +137,6 @@ def raw(self): return self._raw_vector_getter - # calibrated vectors @property diff --git a/py4DSTEM/braggvectors/virtualimage.py b/py4DSTEM/braggvectors/virtualimage.py deleted file mode 100644 index 0bfd9eb61..000000000 --- a/py4DSTEM/braggvectors/virtualimage.py +++ /dev/null @@ -1,77 +0,0 @@ -import numpy as np -from emdfile import tqdmnd - - - - - - -## TODO - - -def make_bragg_mask( - Qshape, - g1, - g2, - radius, - origin, - max_q, - return_sum = True, - **kwargs, - ): - ''' - Creates and returns a mask consisting of circular disks - about the points of a 2D lattice. - - Args: - Qshape (2 tuple): the shape of diffraction space - g1,g2 (len 2 array or tuple): the lattice vectors - radius (number): the disk radius - origin (len 2 array or tuple): the origin - max_q (nuumber): the maxima distance to tile to - return_sum (bool): if False, return a 3D array, where each - slice contains a single disk; if False, return a single - 2D masks of all disks - - Returns: - (2 or 3D array) the mask - ''' - nas = np.asarray - g1,g2,origin = nas(g1),nas(g2),nas(origin) - - # Get N,M, the maximum indices to tile out to - L1 = np.sqrt(np.sum(g1**2)) - H = int(max_q/L1) + 1 - L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) - K = int(max_q/L2) + 1 - - # Compute number of points - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - N += 1 - - #create mask - mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - center = origin + v - mask[:,:,N] = make_detector( - Qshape, - mode = 'circle', - geometry = (center, radius), - ) - N += 1 - - - if return_sum: - mask = np.sum(mask, axis = 2) - return mask - - - diff --git a/py4DSTEM/classes/__init__.py b/py4DSTEM/classes/__init__.py deleted file mode 100644 index 0bacd8a70..000000000 --- a/py4DSTEM/classes/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -_emd_hook = True - -from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction - - diff --git a/py4DSTEM/classes/virtualdiffraction.py b/py4DSTEM/classes/virtualdiffraction.py deleted file mode 100644 index 3831bbefe..000000000 --- a/py4DSTEM/classes/virtualdiffraction.py +++ /dev/null @@ -1,50 +0,0 @@ - -from typing import Optional -import numpy as np - -from py4DSTEM.data import DiffractionSlice,Data - - - -class VirtualDiffraction(DiffractionSlice,Data): - """ - Stores a diffraction-space shaped 2D image with metadata - indicating how this image was generated from a datacube. - """ - def __init__( - self, - data: np.ndarray, - name: Optional[str] = 'virtualdiffraction', - ): - """ - Args: - data (np.ndarray) : the 2D data - name (str) : the name - - Returns: - A new VirtualDiffraction instance - """ - # initialize as a DiffractionSlice - DiffractionSlice.__init__( - self, - data = data, - name = name, - ) - - - # read - @classmethod - def _get_constructor_args(cls,group): - """ - Returns a dictionary of args/values to pass to the class constructor - """ - ar_constr_args = DiffractionSlice._get_constructor_args(group) - args = { - 'data' : ar_constr_args['data'], - 'name' : ar_constr_args['name'], - } - return args - - - - diff --git a/py4DSTEM/datacube/__init__.py b/py4DSTEM/datacube/__init__.py index f1f6e5b99..881966e2f 100644 --- a/py4DSTEM/datacube/__init__.py +++ b/py4DSTEM/datacube/__init__.py @@ -2,5 +2,6 @@ from py4DSTEM.datacube.datacube import DataCube from py4DSTEM.datacube.virtualimage import VirtualImage +from py4DSTEM.datacube.virtualdiffraction import VirtualDiffraction diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index 55428bddc..96ec950ba 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -1,21 +1,22 @@ # Defines the DataCube class, which stores 4D-STEM datacubes import numpy as np -from scipy.ndimage import distance_transform_edt, binary_fill_holes, gaussian_filter1d from scipy.interpolate import interp1d -from scipy.ndimage import ( - binary_opening, binary_dilation, distance_transform_edt) +from scipy.ndimage import (binary_opening, binary_dilation, + distance_transform_edt, binary_fill_holes, gaussian_filter1d) from typing import Optional,Union from emdfile import Array, Metadata, Node, Root, tqdmnd from py4DSTEM.data import Data, Calibration from py4DSTEM.datacube.virtualimage import DataCubeVirtualImager +from py4DSTEM.datacube.virtualdiffraction import DataCubeVirtualDiffraction class DataCube( Array, Data, - DataCubeVirtualImager + DataCubeVirtualImager, + DataCubeVirtualDiffraction, ): """ Storage and processing methods for 4D-STEM datasets. @@ -550,404 +551,6 @@ def filter_hot_pixels( - - - - # Diffraction imaging - - def get_virtual_diffraction( - self, - method = 'max', - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - name = 'virtual_diffracton', - returncalc = True, - ): - """ - Function to calculate virtual diffraction patterns - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - method (str) : defines method used for diffraction pattern, options - are 'mean', 'median', and 'max' - mode (str) : defines mode for selecting area in real space to use - for virtual diffraction. The default is None, which means no - geometry will be applied and the whole datacube will be used - for the calculation. Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright - field - - 'annular' or 'annulus' uses annular detector, like dark - field - - 'rectangle', 'square', 'rectangular', uses rectangular - detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, - values in pixels argument, as follows. The default is None, which - means no geometry will be applied and the whole datacube will be - used for the calculation. If mode is None the geometry will not - be applied. - - 'point': 2-tuple, (rx,ry), ints - - 'circle' or 'circular': nested 2-tuple, ((rx,ry),radius), - - 'annular' or 'annulus': nested 2-tuple, - ((rx,ry),(radius_i,radius_o)) - - 'rectangle', 'square', 'rectangular': 4-tuple, - (rxmin,rxmax,rymin,rymax) - - `mask`: flexible detector, any boolean or floating point 2D - array with the same shape as datacube.Rshape - calibrated (bool): if True, geometry is specified in units of 'A' - instead of pixels. The datacube's calibrations must have its - `"R_pixel_units"` parameter set to "A". If mode is None the - geometry and calibration will not be applied. - shift_center (bool): if True, the difraction patterns are shifted to - account for beam shift or the changing of the origin through the - scan. The datacube's calibration['origin'] parameter must be set. - Only 'max' and 'mean' supported for this option. - verbose (bool): if True, show progress bar - - Returns: - (VirtualDiffraction): the diffraction image - """ - - # perform computation - from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction - from py4DSTEM.process.virtualdiffraction import get_virtual_diffraction - dp = get_virtual_diffraction( - self, - method = method, - mode = mode, - geometry = geometry, - shift_center = shift_center, - calibrated = calibrated, - verbose = verbose, - ) - - # wrap with a py4dstem class - dp = VirtualDiffraction( - data = dp, - name = name - ) - - # add the args used to gen this dp as metadata - dp.metadata = Metadata( - name='gen_params', - data = { - #'gen_func' : - 'method' : method, - 'mode' : mode, - 'geometry' : geometry, - 'shift_center' : shift_center, - 'calibrated' : calibrated, - } - ) - - # add to the tree - self.attach( dp ) - - # return - if returncalc: - return dp - - - def get_dp_max( - self, - method = 'max', - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - name = 'dp_max', - returncalc = True, - ): - """ - Function to calculate maximum virtual diffraction. Default captures - pattern across entire 4D-dataset. - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - mode (str) : defines mode for selecting area in real space to use for - virtual diffraction. The default is None, which means no - geometry will be applied and the whole datacube will be used - for the calculation. Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright - field - - 'annular' or 'annulus' uses annular detector, like dark - field - - 'rectangle', 'square', 'rectangular', uses rectangular - detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, - values in pixels argument, as follows. The default is None, which - means no geometry will be applied and the whole datacube will be - used for the calculation. If mode is None the geometry will not - be applied. - - 'point': 2-tuple, (rx,ry), - rx and ry are each single float or int to define center - - 'circle' or 'circular': nested 2-tuple, ((rx,ry),radius), - - 'annular' or 'annulus': nested 2-tuple, - ((rx,ry),(radius_i,radius_o)), - - 'rectangle', 'square', 'rectangular': 4-tuple, - (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point 2D - array with the same shape as datacube.Rshape - calibrated (bool): if True, geometry is specified in units of 'A' - instead of pixels. The datacube's calibrations must have its - `"R_pixel_units"` parameter set to "A". If mode is None the - geometry and calibration will not be applied. - shift_center (bool) : if True, the difraction patterns are shifted to - account for beam shift or the changing of the origin through the - scan. The datacube's calibration['origin'] parameter must be set. - Only 'max' and 'mean' supported for this option. - verbose (bool): if True, show progress bar - - Returns: - (VirtualDiffraction): the diffraction image - """ - - # perform computation - from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction - from py4DSTEM.process.virtualdiffraction import get_virtual_diffraction - dp = get_virtual_diffraction( - self, - method = method, - mode = mode, - geometry = geometry, - shift_center = shift_center, - calibrated = calibrated, - verbose = verbose, - ) - - # wrap with a py4dstem class - dp = VirtualDiffraction( - data = dp, - name = name - ) - - # add the args used to gen this dp as metadata - dp.metadata = Metadata( - name='gen_params', - data = { - #'gen_func' : - 'method' : method, - 'mode' : mode, - 'geometry' : geometry, - 'shift_center' : shift_center, - 'calibrated' : calibrated, - } - ) - - # add to the tree - self.attach( dp ) - - # return - if returncalc: - return dp - - - def get_dp_mean( - self, - method = 'mean', - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - name = 'dp_mean', - returncalc = True, - ): - """ - Function to calculate mean virtual diffraction. Default captures pattern - across entire 4D-dataset. - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - mode (str) : defines mode for selecting area in real space to use for - virtual diffraction. The default is None, which means no - geometry will be applied and the whole datacube will be used - for the calculation. Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright - field - - 'annular' or 'annulus' uses annular detector, like dark - field - - 'rectangle', 'square', 'rectangular', uses rectangular - detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, - values in pixels argument, as follows. The default is None, - which means no geometry will be applied and the whole datacube - will be used for the calculation. If mode is None the geometry - will not be applied. - - 'point': 2-tuple, (rx,ry), - qx and qy are each single float or int to define center - - 'circle' or 'circular': nested 2-tuple, ((rx,ry),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, - ((rx,ry),(radius_i,radius_o)), - - 'rectangle', 'square', 'rectangular': 4-tuple, - (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point 2D - array with the same shape as datacube.Rshape - calibrated (bool): if True, geometry is specified in units of 'A' - instead of pixels. The datacube's calibrations must have its - `"R_pixel_units"` parameter set to "A". If mode is None the - geometry and calibration will not be applied. - shift_center (bool): if True, the diffraction patterns are shifted to - account for beam shift or the changing of the origin through the - scan. The datacube's calibration['origin'] parameter must be set. - Only 'max' and 'mean' supported for this option. - verbose (bool) : if True, show progress bar - - Returns: - (VirtualDiffraction): the diffraction image - """ - - # perform computation - from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction - from py4DSTEM.process.virtualdiffraction import get_virtual_diffraction - dp = get_virtual_diffraction( - self, - method = method, - mode = mode, - geometry = geometry, - shift_center = shift_center, - calibrated = calibrated, - verbose = verbose, - ) - - # wrap with a py4dstem class - dp = VirtualDiffraction( - data = dp, - name = name, - ) - - # add the args used to gen this dp as metadata - dp.metadata = Metadata( - name='gen_params', - data = { - #'gen_func' : - 'method' : method, - 'mode' : mode, - 'geometry' : geometry, - 'shift_center' : shift_center, - 'calibrated' : calibrated, - } - ) - - # add to the tree - self.attach( dp ) - - # return - if returncalc: - return dp - - def get_dp_median( - self, - method = 'median', - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - name = 'dp_median', - returncalc = True, - ): - """ - Function to calculate median virtual diffraction. Default captures - pattern across entire 4D-dataset. - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - mode (str) : defines mode for selecting area in real space to use for - virtual diffraction. The default is None, which means no - geometry will be applied and the whole datacube will be used - for the calculation. Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright - field - - 'annular' or 'annulus' uses annular detector, like dark - field - - 'rectangle', 'square', 'rectangular', uses rectangular - detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, - values in pixels argument, as follows. The default is None, - which means no geometry will be applied and the whole datacube - will be used for the calculation. If mode is None the geometry - will not be applied. - - 'point': 2-tuple, (rx,ry), - - 'circle' or 'circular': nested 2-tuple, ((rx,ry),radius), - - 'annular' or 'annulus': nested 2-tuple, - ((rx,ry),(radius_i,radius_o)), - - 'rectangle', 'square', 'rectangular': 4-tuple, - (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point 2D - array with the same shape as datacube.Rshape - calibrated (bool): if True, geometry is specified in units of 'A' - instead of pixels. The datacube's calibrations must have its - `"R_pixel_units"` parameter set to "A". If mode is None the - geometry and calibration will not be applied. - shift_center (bool) : if True, the diffraction patterns are shifted to - account for beam shift or the changing of the origin through the - scan. The datacube's calibration['origin'] parameter must be set. - Only 'max' and 'mean' supported for this option. - verbose (bool): if True, show progress bar - - Returns: - (VirtualDiffraction): the diffraction image - """ - - # perform computation - from py4DSTEM.classes.virtualdiffraction import VirtualDiffraction - from py4DSTEM.process.virtualdiffraction import get_virtual_diffraction - dp = get_virtual_diffraction( - self, - method = method, - mode = mode, - geometry = geometry, - shift_center = shift_center, - calibrated = calibrated, - verbose = verbose, - ) - - # wrap with a py4dstem class - dp = VirtualDiffraction( - data = dp, - name = name, - ) - - # add the args used to gen this dp as metadata - dp.metadata = Metadata( - name='gen_params', - data = { - #'gen_func' : - 'method' : method, - 'mode' : mode, - 'geometry' : geometry, - 'shift_center' : shift_center, - 'calibrated' : calibrated, - } - ) - - # add to the tree - self.attach( dp ) - - # return - if returncalc: - return dp - - - - # Probe def get_vacuum_probe( diff --git a/py4DSTEM/datacube/virtualdiffraction.py b/py4DSTEM/datacube/virtualdiffraction.py new file mode 100644 index 000000000..9d1aaa4b7 --- /dev/null +++ b/py4DSTEM/datacube/virtualdiffraction.py @@ -0,0 +1,362 @@ +# Virtual diffraction from a self. Includes: +# * VirtualDiffraction - a container for virtual diffraction data + metadata +# * DataCubeVirtualDiffraction - methods inherited by DataCube for virt diffraction + +import numpy as np +import dask.array as da +from typing import Optional +import inspect + +from emdfile import tqdmnd,Metadata +from py4DSTEM.data import Calibration, DiffractionSlice, Data +from py4DSTEM.visualize.show import show + +# Virtual diffraction container class + +class VirtualDiffraction(DiffractionSlice,Data): + """ + Stores a diffraction-space shaped 2D image with metadata + indicating how this image was generated from a self. + """ + def __init__( + self, + data: np.ndarray, + name: Optional[str] = 'virtualdiffraction', + ): + """ + Args: + data (np.ndarray) : the 2D data + name (str) : the name + + Returns: + A new VirtualDiffraction instance + """ + # initialize as a DiffractionSlice + DiffractionSlice.__init__( + self, + data = data, + name = name, + ) + + # read + @classmethod + def _get_constructor_args(cls,group): + """ + Returns a dictionary of args/values to pass to the class constructor + """ + ar_constr_args = DiffractionSlice._get_constructor_args(group) + args = { + 'data' : ar_constr_args['data'], + 'name' : ar_constr_args['name'], + } + return args + + +# DataCube virtual diffraction methods + +class DataCubeVirtualDiffraction: + + def __init__(self): + pass + + def get_virtual_diffraction( + self, + method, + mask = None, + shift_center = False, + subpixel = False, + verbose = True, + name = 'virtual_diffraction', + returncalc = True + ): + """ + Function to calculate virtual diffraction images. + + Parameters + ---------- + method : str + defines method used for averaging/combining diffraction patterns. + Options are ('mean', 'median', 'max') + mask : None or 2D array + if None (default), all pixels are used. Otherwise, must be a boolean + or floating point or complex array with the same shape as real space. + For bool arrays, only True pixels are used in the computation. + Otherwise a weighted average is performed. + shift_center : bool + toggles shifting the diffraction patterns to account for beam shift. + Currently only supported for 'max' and 'mean' modes. Default is + False. + subpixel : bool + if shift_center is True, toggles subpixel shifts via Fourier + interpolation. Ignored if shift_center is False. + verbose : bool + toggles progress bar + name : string + name for the output DiffractionImage instance + returncalc : bool + toggles returning the output + + Returns + ------- + diff_im : DiffractionImage + """ + # parse inputs + assert method in ('max', 'median', 'mean'), 'check doc strings for supported types' + assert(mask is None or mask.shape == self.Rshape), "mask must be None or real-space shaped" + + + # Calculate + + # ...with no center shifting + if shift_center == False: + + # ...for the whole pattern + if mask is None: + if method == 'mean': + virtual_diffraction = np.mean(self.data, axis=(0,1)) + elif method == 'max': + virtual_diffraction = np.max(self.data, axis=(0,1)) + else: + virtual_diffraction = np.median(self.data, axis=(0,1)) + + # ...for boolean masks + elif mask.dtype == bool: + mask_indices = np.nonzero(mask) + if method == 'mean': + virtual_diffraction = np.mean( + self.data[mask_indices[0],mask_indices[1],:,:], axis=0) + elif method == 'max': + virtual_diffraction = np.max( + self.data[mask_indices[0],mask_indices[1],:,:], axis=0) + else: + virtual_diffraction = np.median( + self.data[mask_indices[0],mask_indices[1],:,:], axis=0) + + # ...for complex and floating point masks + else: + # allocate space + if mask.dtype == 'complex': + virtual_diffraction = np.zeros(self.Qshape, dtype='complex') + else: + virtual_diffraction = np.zeros(self.Qshape) + # set computation method + if method == 'mean': + fn = np.sum + elif method == 'max': + fn = np.max + else: + fn = np.median + # loop + for qx,qy in tqdmnd( + self.Q_Nx, + self.Q_Ny, + disable = not verbose, + ): + virtual_diffraction[qx,qy] = fn( np.squeeze(self.data[:,:,qx,qy])*mask ) + # normalize weighted means + if method == 'mean': + virtual_diffraction /= np.sum(mask) + + + # ...with center shifting + else: + assert method in ('max', 'mean'),\ + "only 'mean' and 'max' are supported for center-shifted virtual diffraction" + + # Get calibration metadata + assert(self.calibration.get_origin() is not None), "origin is not calibrated" + x0, y0 = self.calibration.get_origin() + x0_mean, y0_mean = self.calibration.get_origin_mean() + + # get shifts + qx_shift = x0_mean-x0 + qy_shift = y0_mean-y0 + + + # ...for integer shifts + if not subpixel: + + # round shifts -> int + qx_shift = qshift.round().astype(int) + qy_shift = qshift.round().astype(int) + + # ...for boolean masks and unmasked + if mask is None or mask.dtype==bool: + # get scan points + mask = np.ones(self.Rshape,dtype=bool) if mask is None else mask + mask_indices = np.nonzero(mask) + # allocate space + virtual_diffraction = np.zeros(self.Qshape) + # loop + for rx,ry in zip(mask_indices[0],mask_indices[1]): + # get shifted DP + DP = np.roll( + self.data[rx,ry, :,:,], + (qx_shift[rx,ry], qy_shift[rx,ry]), + axis=(0,1), + ) + # compute + if method == 'mean': + virtual_diffraction += DP + elif method == 'max': + virtual_diffraction = np.maximum(virtual_diffraction, DP) + # normalize means + if method == 'mean': + virtual_diffraction /= len(mask_indices[0]) + + # ...for floating point and complex masks + else: + # allocate space + if mask.dtype == 'complex': + virtual_diffraction = np.zeros(self.Qshape, dtype = 'complex') + else: + virtual_diffraction = np.zeros(self.Qshape) + # loop + for rx,ry in tqdmnd( + self.R_Nx, + self.R_Ny, + disable = not verbose, + ): + # get shifted DP + DP = np.roll( + self.data[rx,ry, :,:,], + (qx_shift[rx,ry], qy_shift[rx,ry]), + axis=(0,1), + ) + # compute + w = mask[rx,ry] + if method == 'mean': + virtual_diffraction += DP*w + elif method == 'max': + virtual_diffraction = np.maximum(virtual_diffraction, DP*w) + if method == 'mean': + virtual_diffraction /= np.sum(mask) + + # TODO subpixel shifting + else: + raise Exception("subpixel shifting has not been implemented yet!") + pass + + + # wrap, add to tree, and return + + # wrap in DiffractionImage + ans = VirtualDiffraction( + data = virtual_diffraction, + name = name + ) + + # add the args used to gen this dp as metadata + ans.metadata = Metadata( + name='gen_params', + data = { + '_calling_method' : inspect.stack()[0][3], + '_calling_class' : __class__.__name__, + 'method' : method, + 'mask' : mask, + 'shift_center' : shift_center, + 'subpixel' : subpixel, + 'verbose' : verbose, + 'name' : name, + 'returncalc' : returncalc + } + ) + + # add to the tree + self.attach( ans ) + + # return + if returncalc: + return ans + + + + # additional interfaces + + def get_dp_max( + self, + returncalc = True, + ): + """ + Calculates the max diffraction pattern. + + Calls `DataCube.get_virtual_diffraction` - see that method's docstring + for more custimizable virtual diffraction. + + Parameters + ---------- + returncalc : bool + toggles returning the answer + + Returns + ------- + max_dp : VirtualDiffraction + """ + return self.get_virtual_diffraction( + method = 'max', + mask = None, + shift_center = False, + subpixel = False, + verbose = True, + name = 'dp_max', + returncalc = True + ) + + def get_dp_mean( + self, + returncalc = True, + ): + """ + Calculates the mean diffraction pattern. + + Calls `DataCube.get_virtual_diffraction` - see that method's docstring + for more custimizable virtual diffraction. + + Parameters + ---------- + returncalc : bool + toggles returning the answer + + Returns + ------- + mean_dp : VirtualDiffraction + """ + return self.get_virtual_diffraction( + method = 'mean', + mask = None, + shift_center = False, + subpixel = False, + verbose = True, + name = 'dp_mean', + returncalc = True + ) + + def get_dp_median( + self, + returncalc = True, + ): + """ + Calculates the max diffraction pattern. + + Calls `DataCube.get_virtual_diffraction` - see that method's docstring + for more custimizable virtual diffraction. + + Parameters + ---------- + returncalc : bool + toggles returning the answer + + Returns + ------- + max_dp : VirtualDiffraction + """ + return self.get_virtual_diffraction( + method = 'median', + mask = None, + shift_center = False, + subpixel = False, + verbose = True, + name = 'dp_median', + returncalc = True + ) + diff --git a/py4DSTEM/datacube/virtualimage.py b/py4DSTEM/datacube/virtualimage.py index 3d721431b..7b7b315be 100644 --- a/py4DSTEM/datacube/virtualimage.py +++ b/py4DSTEM/datacube/virtualimage.py @@ -7,6 +7,7 @@ import numpy as np import dask.array as da from typing import Optional +import inspect from emdfile import tqdmnd,Metadata from py4DSTEM.data import Calibration, RealSlice, Data @@ -286,6 +287,8 @@ def _apply_mask_dask(self,mask): ans.metadata = Metadata( name = 'gen_params', data = { + '_calling_method' : inspect.stack()[0][3], + '_calling_class' : __class__.__name__, 'mode' : mode, 'geometry' : geometry, 'centered' : centered, @@ -617,19 +620,7 @@ def make_detector( - - - - - - - - - - - - -# TODO - where does this go? +# TODO - where should this go? def make_bragg_mask( Qshape, @@ -697,121 +688,3 @@ def make_bragg_mask( -# TODO - these need to move elsewhere! - -def get_virtual_image_pointlistarray( - peaks, - mode = None, - geometry = None, - ): - """ - Make a virtual image from a pointlist array. - TODO - implement more virtual detectors. - - Args: - peaks (PointListArray): List of all peaks and intensities. - mode (str) : defines geometry mode for calculating virtual image. - Options: - - 'circular' or 'circle' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - geometry (variable) : valid entries are determined by the `mode`, values in pixels - argument, as follows: - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) - - Returns: - im_virtual (2D numpy array): the calculated virtual image - """ - - # Set geometry - if mode is None: - if geometry is None: - center = None - radial_range = np.array((0,np.inf)) - else: - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - if isinstance(geometry[1], int) or isinstance(geometry[1], float): - radial_range = np.array((0,geometry[1])) - elif len(geometry[1]) == 0: - radial_range = None - else: - radial_range = np.array(geometry[1]) - elif mode == 'circular' or mode == 'circle': - radial_range = np.array((0,geometry[1])) - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - elif mode == 'annular' or mode == 'annulus': - radial_range = np.array(geometry[1]) - if len(geometry[0]) == 0: - center = None - else: - center = np.array(geometry[0]) - - - - # init - im_virtual = np.zeros(peaks.shape) - - # Generate image - for rx,ry in tqdmnd(peaks.shape[0],peaks.shape[1]): - p = peaks.get_pointlist(rx,ry) - if p.data.shape[0] > 0: - if radial_range is None: - im_virtual[rx,ry] = np.sum(p.data['intensity']) - else: - if center is None: - qr = np.hypot(p.data['qx'],p.data['qy']) - else: - qr = np.hypot(p.data['qx'] - center[0],p.data['qy'] - center[1]) - sub = np.logical_and( - qr >= radial_range[0], - qr < radial_range[1]) - if np.sum(sub) > 0: - im_virtual[rx,ry] = np.sum(p.data['intensity'][sub]) - - return im_virtual - - -def get_virtual_image_braggvectors( - bragg_peaks, - mode = None, - geometry = None, - ): - ''' - Function to calculate virtual images from braggvectors / pointlist arrays. - TODO - implement these detectors for braggvectors - - Args: - bragg_peaks (BraggVectors) : BraggVectors class object which stores bragg peaks - mode (str) : defines geometry mode for calculating virtual image. - Options: - - 'circular' or 'circle' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - geometry (variable) : valid entries are determined by the `mode`, values in pixels - argument, as follows: - - 'circle' or 'circular': nested 2-tuple, ((qx,qy),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - Note that (qx,qy) can be skipped, which assumes peaks centered at (0,0) - - Returns: - im_virtual (2D numpy array): the calculated virtual image - ''' - - virtual_image = get_virtual_image_pointlistarray( - bragg_peaks.vectors, - mode = mode, - geometry = geometry, - ) - - return virtual_image - diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index 825892fa9..a9d188b03 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -45,9 +45,7 @@ ) from py4DSTEM.datacube import ( DataCube, - VirtualImage -) -from py4DSTEM.classes import ( + VirtualImage, VirtualDiffraction, ) diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 9eda852a1..2c413c5d2 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -327,7 +327,7 @@ def _euler_angle_rotate_volume( """ Rotate 3D volume using alpha, beta, gamma Euler angles according to convention: - - \-alpha tilt around first axis (z) + - \alpha tilt around first axis (z) - \beta tilt around second axis (x) - \alpha tilt around first axis (z) From 2db764a0c4e6772f478bdac86af8663a65aa4610 Mon Sep 17 00:00:00 2001 From: cophus Date: Fri, 7 Jul 2023 12:56:59 -0700 Subject: [PATCH 136/362] Background modeling --- py4DSTEM/process/polar/polar_datacube.py | 2 + py4DSTEM/process/polar/polar_peaks.py | 249 ++++++++++++++++++++--- 2 files changed, 226 insertions(+), 25 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 4610364a9..e9b3fcbfa 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -102,9 +102,11 @@ def __init__( from py4DSTEM.process.polar.polar_peaks import ( find_peaks_single_pattern, find_peaks, + refine_peaks_local, refine_peaks, plot_radial_peaks, plot_radial_background, + model_radial_background, make_orientation_histogram, ) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index dda307188..c9584d95f 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -244,13 +244,13 @@ def find_peaks_single_pattern( # Output data as a pointlist peaks_polar = PointList( peaks_all.ravel().view([ - ('qt', np.float), - ('qr', np.float), - ('intensity', np.float), - ('prom_annular', np.float), - ('sigma_annular', np.float), - ('prom_radial', np.float), - ('sigma_radial', np.float), + ('qt', float), + ('qr', float), + ('intensity', float), + ('prom_annular', float), + ('sigma_annular', float), + ('prom_radial', float), + ('sigma_radial', float), ]), name = 'peaks_polar') @@ -415,10 +415,10 @@ def find_peaks( self.background_radial_mask[rx,ry] = sig_bg_mask -def refine_peaks( +def refine_peaks_local( self, mask = None, - radial_background_subtract = True, + radial_background_subtract = False, reset_fits_to_init_positions = False, fit_range_sigma_annular = 2.0, fit_range_sigma_radial = 2.0, @@ -592,9 +592,11 @@ def refine_peaks( def plot_radial_peaks( self, + q_pixel_units = False, qmin = None, qmax = None, qstep = None, + label_y_axis = False, figsize = (8,4), returnfig = False, ): @@ -606,7 +608,10 @@ def plot_radial_peaks( # Get all peak data vects = np.concatenate( [self.peaks[i,j].data for i in range(self._datacube.Rshape[0]) for j in range(self._datacube.Rshape[1])]) - qr = vects['qr'] * self._radial_step + if q_pixel_units: + qr = vects['qr'] + else: + qr = (vects['qr'] + self.qmin) * self._radial_step intensity = vects['intensity'] # bins @@ -618,9 +623,11 @@ def plot_radial_peaks( qstep = self.qq[1] - self.qq[0] q_bins = np.arange(qmin,qmax,qstep) q_num = q_bins.shape[0] + if q_pixel_units: + q_bins /= self._radial_step # histogram - q_ind = (qr - qmin) / qstep + q_ind = (qr - q_bins[0]) / (q_bins[1] - q_bins[0]) qf = np.floor(q_ind).astype("int") dq = q_ind - qf @@ -647,23 +654,184 @@ def plot_radial_peaks( linewidth = 2, ) ax.set_xlim((q_bins[0],q_bins[-1])) - ax.set_xlabel( - 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', - fontsize = 14, - ) + if q_pixel_units: + ax.set_xlabel( + 'Scattering Angle (pixels)', + fontsize = 14, + ) + else: + ax.set_xlabel( + 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', + fontsize = 14, + ) ax.set_ylabel( 'Total Peak Signal', fontsize = 14, ) + if not label_y_axis: + ax.tick_params( + left = False, + labelleft = False) if returnfig: return fig,ax +def model_radial_background( + self, + ring_position = None, + ring_sigma = None, + ring_int = None, + refine_model = True, + plot_result = True, + ): + """ + User provided radial background model, of the form: + + int = int_const + + int_0 * exp( - q**2 / (2*s0**2) ) + + int_1 * exp( - (q - q_1)**2 / (2*s1**2) ) + + ... + + int_n * exp( - (q - q_n)**2 / (2*sn**2) ) + + where n is the number of amorphous halos / rings included in the fit. + + """ + + # Get mean radial background and mask + self.background_radial_mean = np.sum( + self.background_radial * self.background_radial_mask, + axis=(0,1)) + background_radial_mean_norm = np.sum( + self.background_radial_mask, + axis=(0,1)) + self.background_mask = \ + background_radial_mean_norm > (np.max(background_radial_mean_norm)*0.05) + self.background_radial_mean[self.background_mask] \ + /= background_radial_mean_norm[self.background_mask] + self.background_radial_mean[np.logical_not(self.background_mask)] = 0 + + # init + if ring_position is not None: + ring_position = np.atleast_1d(np.array(ring_position)) + num_rings = ring_position.shape[0] + else: + num_rings = 0 + self.background_coefs = np.zeros(3 + 3*num_rings) + + if ring_sigma is None: + ring_sigma = np.atleast_1d(np.ones(num_rings)) \ + * self.polar_shape[1] * 0.05 * self._radial_step + else: + ring_sigma = np.atleast_1d(np.array(ring_sigma)) + + # Background model initial parameters + int_const = np.min(self.background_radial_mean) + int_0 = np.max(self.background_radial_mean) - int_const + sigma_0 = self.polar_shape[1] * 0.25 * self._radial_step + self.background_coefs[0] = int_const + self.background_coefs[1] = int_0 + self.background_coefs[2] = sigma_0 + + # Additional Gaussians + if ring_int is None: + # Estimate peak intensities + sig_0 = int_const + int_0*np.exp(self.qq**2/(-2*sigma_0**2)) + sig_peaks = np.maximum(self.background_radial_mean - sig_0, 0.0) + + ring_int = np.atleast_1d(np.zeros(num_rings)) + for a0 in range(num_rings): + ind = np.argmin(np.abs(self.qq - ring_position[a0])) + ring_int[a0] = sig_peaks[ind] + + else: + ring_int = np.atleast_1d(np.array(ring_int)) + for a0 in range(num_rings): + self.background_coefs[3*a0+3] = ring_int[a0] + self.background_coefs[3*a0+4] = ring_sigma[a0] + self.background_coefs[3*a0+5] = ring_position[a0] + + # Create background model + def background_model(q, *coefs): + coefs = np.squeeze(np.array(coefs)) + num_rings = np.round((coefs.shape[0] - 3)/3).astype('int') + + sig = np.ones(q.shape[0])*coefs[0] + sig += coefs[1]*np.exp(q**2/(-2*coefs[2]**2)) + + for a0 in range(num_rings): + sig += coefs[3*a0+3]*np.exp( + (q-coefs[3*a0+5])**2 / (-2*coefs[3*a0+4]**2)) + + return sig + + self.background_model = background_model + + # Refine background model coefficients + if refine_model: + self.background_coefs = curve_fit( + self.background_model, + self.qq[self.background_mask], + self.background_radial_mean[self.background_mask], + p0 = self.background_coefs, + xtol = 1e-12, + # bounds = (lb,ub), + )[0] + + # plotting + if plot_result: + self.plot_radial_background( + q_pixel_units = False, + plot_background_model = True, + ) + + + +def refine_peaks( + self, + mask = None, + # reset_fits_to_init_positions = False, + min_num_pixels_fit = 10, + progress_bar = True, + ): + """ + Use global fitting model for all images. Requires an background model + specified with self.model_radial_background(). + + Parameters + -------- + mask: np.array + Mask image to apply to all images + radial_background_subtract: bool + Subtract radial background before fitting + reset_fits_to_init_positions: bool + Use the initial peak parameters for fitting + min_num_pixels_fit: int + Minimum number of pixels to perform fitting + progress_bar: bool + Enable progress bar + + Returns + -------- + + """ + + # init + + + + # Main loop + + + + def plot_radial_background( self, + q_pixel_units = False, + label_y_axis = False, + plot_background_model = False, figsize = (8,4), returnfig = False, ): @@ -696,9 +864,14 @@ def plot_radial_background( self.background_radial_std = np.sqrt(self.background_radial_var) + if q_pixel_units: + q_axis = np.arange(self.polar_shape[1]) + else: + q_axis = self.qq[self.background_mask] + fig,ax = plt.subplots(figsize = figsize) ax.fill_between( - self.qq[self.background_mask], + q_axis, self.background_radial_mean[self.background_mask] \ - self.background_radial_std[self.background_mask], self.background_radial_mean[self.background_mask] \ @@ -707,22 +880,48 @@ def plot_radial_background( alpha=0.2, ) ax.plot( - self.qq[self.background_mask], + q_axis, self.background_radial_mean[self.background_mask], color = 'r', linewidth = 2, ) + + # overlay fitting model + if plot_background_model: + sig = self.background_model( + self.qq, + self.background_coefs, + ) + ax.plot( + q_axis, + sig, + color = 'k', + linewidth = 2, + linestyle = '--' + ) + + # plot appearance ax.set_xlim(( - self.qq[0], - self.qq[-1])) - ax.set_xlabel( - 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', - fontsize = 14, - ) + q_axis[0], + q_axis[-1])) + if q_pixel_units: + ax.set_xlabel( + 'Scattering Angle (pixels)', + fontsize = 14, + ) + else: + ax.set_xlabel( + 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', + fontsize = 14, + ) ax.set_ylabel( 'Background Signal', fontsize = 14, ) + if not label_y_axis: + ax.tick_params( + left = False, + labelleft = False) if returnfig: return fig,ax @@ -820,10 +1019,10 @@ def make_orientation_histogram( dy = y - yF add_data = False - - q = self.peaks[rx,ry]['qr'] * self._radial_step + q = (self.peaks[rx,ry]['qr'] + self.qmin) * self._radial_step r2 = q**2 sub = np.logical_and(r2 >= radial_ranges_2[a0,0], r2 < radial_ranges_2[a0,1]) + if np.any(sub): add_data = True intensity = self.peaks[rx,ry]['intensity'][sub] From 4db8eb50be296dd56cd59d1faf1690a48fe2bc4f Mon Sep 17 00:00:00 2001 From: cophus Date: Fri, 7 Jul 2023 13:22:31 -0700 Subject: [PATCH 137/362] Adding full refinement --- py4DSTEM/process/polar/polar_peaks.py | 72 +++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index c9584d95f..e040e4027 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -798,6 +798,8 @@ def refine_peaks( Use global fitting model for all images. Requires an background model specified with self.model_radial_background(). + TODO: add fitting reset + Parameters -------- mask: np.array @@ -817,14 +819,78 @@ def refine_peaks( """ # init - + self.peaks_refine = PointListArray( + dtype = [ + ('qt', ' Date: Fri, 7 Jul 2023 14:32:25 -0700 Subject: [PATCH 138/362] Full pattern fitting for polar images is working! --- py4DSTEM/process/polar/polar_peaks.py | 134 ++++++++++++++++++++------ 1 file changed, 103 insertions(+), 31 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index e040e4027..dceb13859 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -791,6 +791,7 @@ def refine_peaks( self, mask = None, # reset_fits_to_init_positions = False, + scale_sigma_estimate = 0.5, min_num_pixels_fit = 10, progress_bar = True, ): @@ -808,6 +809,8 @@ def refine_peaks( Subtract radial background before fitting reset_fits_to_init_positions: bool Use the initial peak parameters for fitting + scale_sigma_estimate: float + Factor to reduce sigma of peaks by, to prevent fit from running away. min_num_pixels_fit: int Minimum number of pixels to perform fitting progress_bar: bool @@ -818,20 +821,6 @@ def refine_peaks( """ - # init - self.peaks_refine = PointListArray( - dtype = [ - ('qt', ' Date: Fri, 7 Jul 2023 14:43:12 -0700 Subject: [PATCH 139/362] Functional fitting code, cleaning up --- py4DSTEM/process/polar/polar_peaks.py | 63 ++++++++++++++++----------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index dceb13859..9383a194e 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -6,6 +6,7 @@ from scipy.signal import peak_prominences from skimage.feature import peak_local_max from scipy.optimize import curve_fit +import warnings # from emdfile import tqdmnd, PointList, PointListArray from py4DSTEM import tqdmnd, PointList, PointListArray @@ -799,7 +800,9 @@ def refine_peaks( Use global fitting model for all images. Requires an background model specified with self.model_radial_background(). - TODO: add fitting reset + TODO: add fitting reset + add min number pixels condition + track any failed fitting points, output as a boolean array Parameters -------- @@ -850,16 +853,16 @@ def refine_peaks( name = 'peaks_polardata_refined', ) self.background_refine = np.zeros(( - self.background_radial.shape[0], - self.background_radial.shape[0], + self._datacube.Rshape[0], + self._datacube.Rshape[1], np.round(3*num_rings+3).astype('int'), )) # Main loop over probe positions for rx, ry in tqdmnd( - np.arange(40,41),#self._datacube.shape[0], - np.arange(70,71),#self._datacube.shape[1], + self._datacube.shape[0], + self._datacube.shape[1], desc="Refining peaks ", unit=" probe positions", disable=not progress_bar): @@ -922,32 +925,40 @@ def fit_image(basis, *coefs): return sig # refine fitting model - coefs_all = curve_fit( - fit_image, - basis[mask_bool.ravel(),:], - im_polar[mask_bool], - p0 = coefs_all, - xtol = 1e-12, - # bounds = (lb,ub), - )[0] + try: + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + coefs_all = curve_fit( + fit_image, + basis[mask_bool.ravel(),:], + im_polar[mask_bool], + p0 = coefs_all, + xtol = 1e-12, + # bounds = (lb,ub), + )[0] + + # Output refined peak parameters + coefs_peaks = np.reshape( + coefs_all[(3*num_rings+3):], + (5,num_peaks)).T + self.peaks_refine[rx,ry] = PointList( + coefs_peaks.ravel().view([ + ('qt', float), + ('qr', float), + ('intensity', float), + ('sigma_annular', float), + ('sigma_radial', float), + ]), + name = 'peaks_polar') + except: + # if fitting has failed, we will output the mean background signal, + # but none of the peaks. + pass # Output refined parameters for background coefs_bg = coefs_all[:(3*num_rings+3)] self.background_refine[rx,ry] = coefs_bg - # Output refined peak parameters - coefs_peaks = np.reshape( - coefs_all[(3*num_rings+3):], - (5,num_peaks)).T - self.peaks_refine[rx,ry] = PointList( - coefs_peaks.ravel().view([ - ('qt', float), - ('qr', float), - ('intensity', float), - ('sigma_annular', float), - ('sigma_radial', float), - ]), - name = 'peaks_polar') # # Testing # im_fit = np.reshape( From 4b63a3a26a4f51f9e04ec6760bc96d2065fbf5d9 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 7 Jul 2023 17:21:08 -0700 Subject: [PATCH 140/362] Force COM measured for DPC --- .../process/phase/iterative_base_class.py | 71 +++++++++++-------- py4DSTEM/process/phase/iterative_dpc.py | 24 +++++-- .../iterative_overlap_magnetic_tomography.py | 6 +- .../phase/iterative_overlap_tomography.py | 6 +- 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 322de95bd..5888292c3 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -280,7 +280,7 @@ def _extract_intensities_and_calibrations_from_datacube( # Copies intensities to device casting to float32 xp = self._xp - intensities = xp.asarray(datacube.data, dtype=xp.float32) + intensities = datacube.data self._grid_scan_shape = intensities.shape[:2] # Extracts calibrations @@ -413,6 +413,7 @@ def _calculate_intensities_center_of_mass( dp_mask: np.ndarray = None, fit_function: str = "plane", com_shifts: np.ndarray = None, + com_measured: np.ndarray = None, ): """ Common preprocessing function to compute and fit diffraction intensities CoM @@ -425,9 +426,10 @@ def _calculate_intensities_center_of_mass( If not None, apply mask to datacube amplitude fit_function: str, optional 2D fitting function for CoM fitting. One of 'plane','parabola','bezier_two' - com_shifts, np.ndarray, optional + com_shifts, tuple of ndarrays (CoMx measured, CoMy measured) If not None, com_shifts are fitted on the measured CoM values. - + com_measured: tuple of ndarrays (CoMx measured, CoMy measured) + If not None, com_measured are passed as com_measured_x, com_measured_y Returns ------- @@ -448,39 +450,48 @@ def _calculate_intensities_center_of_mass( xp = self._xp asnumpy = self._asnumpy - # Coordinates - kx = xp.arange(intensities.shape[-2], dtype=xp.float32) - ky = xp.arange(intensities.shape[-1], dtype=xp.float32) - kya, kxa = xp.meshgrid(ky, kx) + intensities = xp.asarray(intensities, dtype=xp.float32) + + # for ptycho + if com_measured: + com_measured_x, com_measured_y = com_measured - # calculate CoM - if dp_mask is not None: - if dp_mask.shape != intensities.shape[-2:]: - raise ValueError( - ( - f"Mask shape should be (Qx,Qy):{intensities.shape[-2:]}, " - f"not {dp_mask.shape}" - ) - ) - intensities_mask = intensities * xp.asarray(dp_mask, dtype=xp.float32) else: - intensities_mask = intensities + # Coordinates + kx = xp.arange(intensities.shape[-2], dtype=xp.float32) + ky = xp.arange(intensities.shape[-1], dtype=xp.float32) + kya, kxa = xp.meshgrid(ky, kx) - intensities_sum = xp.sum(intensities_mask, axis=(-2, -1)) - com_measured_x = ( - xp.sum(intensities_mask * kxa[None, None], axis=(-2, -1)) / intensities_sum - ) - com_measured_y = ( - xp.sum(intensities_mask * kya[None, None], axis=(-2, -1)) / intensities_sum - ) + # calculate CoM + if dp_mask is not None: + if dp_mask.shape != intensities.shape[-2:]: + raise ValueError( + ( + f"Mask shape should be (Qx,Qy):{intensities.shape[-2:]}, " + f"not {dp_mask.shape}" + ) + ) + intensities_mask = intensities * xp.asarray(dp_mask, dtype=xp.float32) + else: + intensities_mask = intensities + + intensities_sum = xp.sum(intensities_mask, axis=(-2, -1)) + com_measured_x = ( + xp.sum(intensities_mask * kxa[None, None], axis=(-2, -1)) + / intensities_sum + ) + com_measured_y = ( + xp.sum(intensities_mask * kya[None, None], axis=(-2, -1)) + / intensities_sum + ) - # Fit function to center of mass if com_shifts is None: com_shifts = fit_origin( (asnumpy(com_measured_x), asnumpy(com_measured_y)), fitfunction=fit_function, ) + # Fit function to center of mass com_fitted_x = xp.asarray(com_shifts[0], dtype=xp.float32) com_fitted_y = xp.asarray(com_shifts[1], dtype=xp.float32) @@ -992,8 +1003,8 @@ def _solve_for_center_of_mass_relative_rotation( cmap = kwargs.pop("cmap", "RdBu_r") extent = [ 0, - self._scan_sampling[1] * self._intensities.shape[1], - self._scan_sampling[0] * self._intensities.shape[0], + self._scan_sampling[1] * _com_measured_x.shape[1], + self._scan_sampling[0] * _com_measured_x.shape[0], 0, ] @@ -1030,8 +1041,8 @@ def _solve_for_center_of_mass_relative_rotation( extent = [ 0, - self._scan_sampling[1] * self._intensities.shape[1], - self._scan_sampling[0] * self._intensities.shape[0], + self._scan_sampling[1] * com_x.shape[1], + self._scan_sampling[0] * com_x.shape[0], 0, ] diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 583128da5..4be160c64 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -4,7 +4,7 @@ """ import warnings -from typing import Tuple +from typing import Tuple, Union, Sequence import matplotlib.pyplot as plt import numpy as np @@ -238,7 +238,8 @@ def preprocess( fit_function: str = "plane", force_com_rotation: float = None, force_com_transpose: bool = None, - force_com_shifts: float = None, + force_com_shifts: Union[Sequence[np.ndarray], Sequence[float]] = None, + force_com_measured: Sequence[np.ndarray] = None, plot_center_of_mass: str = "default", plot_rotation: bool = True, **kwargs, @@ -269,6 +270,8 @@ def preprocess( Force whether diffraction intensities need to be transposed. force_com_shifts: tuple of ndarrays (CoMx, CoMy) Force CoM fitted shifts + force_com_measured: tuple of ndarrays (CoMx measured, CoMy measured) + Force CoM measured shifts plot_center_of_mass: str, optional If 'default', the corrected CoM arrays will be displayed If 'all', the computed and fitted CoM arrays will be displayed @@ -286,12 +289,18 @@ def preprocess( self._dp_mask = dp_mask if self._datacube is None: - raise ValueError( - ( - "The preprocess() method requires a DataCube. " - "Please run dpc.attach_datacube(DataCube) first." + if force_com_measured is None: + raise ValueError( + ( + "The preprocess() method requires either a DataCube " + "or `force_com_measured`. " + "Please run dpc.attach_datacube(DataCube) to attach DataCube." + ) + ) + else: + self._datacube = DataCube( + data=np.empty(force_com_measured[0].shape + (1, 1)) ) - ) self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, @@ -310,6 +319,7 @@ def preprocess( dp_mask=self._dp_mask, fit_function=fit_function, com_shifts=force_com_shifts, + com_measured=force_com_measured, ) ( diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 0c751cd33..7c88931a5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -2488,11 +2488,7 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - ( - self._object, - self._probe, - _, - ) = self._constraints( + (self._object, self._probe, _,) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 61d40473d..6b0a16e2e 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2212,11 +2212,7 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - ( - self._object, - self._probe, - _, - ) = self._constraints( + (self._object, self._probe, _,) = self._constraints( self._object, self._probe, None, From 14c6865463c790c766938c1af3fba31378a8d110 Mon Sep 17 00:00:00 2001 From: cophus Date: Fri, 7 Jul 2023 18:45:23 -0700 Subject: [PATCH 141/362] New options for flowline orientation maps Allowing peak sigma in bins --- py4DSTEM/process/polar/polar_peaks.py | 25 +++++++++++++++++++++++-- py4DSTEM/visualize/show.py | 8 ++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 9383a194e..2bbac32e4 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -1083,6 +1083,9 @@ def make_orientation_histogram( orientation_offset_degrees: float = 0.0, orientation_separate_bins: bool = False, upsample_factor: float = 4.0, + use_refined_peaks = True, + use_peak_sigma = False, + peak_sigma_samples = 6, theta_step_deg: float = None, sigma_x: float = 1.0, sigma_y: float = 1.0, @@ -1104,6 +1107,8 @@ def make_orientation_histogram( orientation_offset_degrees (float): Offset for orientation angles orientation_separate_bins (bool): whether to place multiple angles into multiple radial bins. upsample_factor (float): Upsample factor + use_refined_peaks (float): Use refined peak positions + use_peak_sigma (float): Spread signal along annular direction using measured std. theta_step_deg (float): Step size along annular direction in degrees sigma_x (float): Smoothing in x direction before upsample sigma_y (float): Smoothing in x direction before upsample @@ -1145,6 +1150,10 @@ def make_orientation_histogram( size_output[1], num_theta_bins]) + if use_peak_sigma: + v_sigma = np.linspace(-2,2,2*peak_sigma_samples+1) + w_sigma = np.exp(-v_sigma**2/2) + # Loop over all probe positions for a0 in range(num_radii): t = "Generating histogram " + str(a0) @@ -1168,7 +1177,10 @@ def make_orientation_histogram( dy = y - yF add_data = False - q = (self.peaks[rx,ry]['qr'] + self.qmin) * self._radial_step + if use_refined_peaks: + q = self.peaks_refine[rx,ry]['qr'] + else: + q = (self.peaks[rx,ry]['qr'] + self.qmin) * self._radial_step r2 = q**2 sub = np.logical_and(r2 >= radial_ranges_2[a0,0], r2 < radial_ranges_2[a0,1]) @@ -1177,13 +1189,22 @@ def make_orientation_histogram( intensity = self.peaks[rx,ry]['intensity'][sub] # Angles of all peaks - theta = self.peaks[rx,ry]['qt'][sub] * self._annular_step + if use_refined_peaks: + theta = self.peaks_refine[rx,ry]['qt'][sub] + else: + theta = self.peaks[rx,ry]['qt'][sub] * self._annular_step if orientation_flip_sign: theta *= -1 theta += orientation_offset_degrees t = theta / dtheta + # If needed, expand signal using peak sigma to write into multiple bins + if use_peak_sigma: + theta_std = self.peaks_refine[rx,ry]['sigma_annular'][sub] / dtheta + t = (t[:,None] + theta_std[:,None]*v_sigma[None,:]).ravel() + intensity = (intensity[:,None] * w_sigma[None,:]).ravel() + if add_data: tF = np.floor(t).astype('int') dt = t - tF diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 45a5b7395..b8df4047c 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -567,8 +567,12 @@ def show( ax.matshow(mask_display,cmap=cmap,alpha=mask_alpha,vmin=vmin,vmax=vmax) # ...or, plot its histogram else: - hist,bin_edges = np.histogram(_ar,bins=np.linspace(np.min(_ar), - np.max(_ar),num=n_bins)) + # hist,bin_edges = np.histogram( + # _ar, + # bins=np.linspace(np.min(_ar),np.max(_ar),num=n_bins)) + hist,bin_edges = np.histogram( + _ar, + bins=np.linspace(vmin,vmax,num=n_bins)) w = bin_edges[1]-bin_edges[0] x = bin_edges[:-1]+w/2. ax.bar(x,hist,width=w) From 696bc338a708896df122791f591d4278b6db369a Mon Sep 17 00:00:00 2001 From: cophus Date: Fri, 7 Jul 2023 18:47:13 -0700 Subject: [PATCH 142/362] Cleaning up --- py4DSTEM/process/polar/polar_peaks.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 2bbac32e4..3f367b398 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -1157,9 +1157,7 @@ def make_orientation_histogram( # Loop over all probe positions for a0 in range(num_radii): t = "Generating histogram " + str(a0) - # for rx, ry in tqdmnd( - # *bragg_peaks.shape, desc=t,unit=" probe positions", disable=not progress_bar - # ): + for rx, ry in tqdmnd( *size_input, desc=t, From 0e69450905db00584c7f88c25a8d71a5eb375c1d Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 8 Jul 2023 07:00:14 -0700 Subject: [PATCH 143/362] bug fix --- py4DSTEM/process/phase/iterative_parallax.py | 1 + 1 file changed, 1 insertion(+) diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 5ab4c6cdd..576342631 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -171,6 +171,7 @@ def preprocess( self._datacube, require_calibrations=True, ) + self._intensities = xp.asarray(self._intensities, dtype=xp.float32) # make sure mean diffraction pattern is shaped correctly if (self._dp_mean.shape[0] != self._intensities.shape[2]) or ( From 1990b8e9ea456dd9eedd2578565bcc5067e8b981 Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:04:59 -0700 Subject: [PATCH 144/362] Adding probe amplitude regularization --- py4DSTEM/process/phase/utils.py | 242 ++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index d57ad820a..8442b6cbc 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -3,6 +3,7 @@ import matplotlib.pyplot as plt import numpy as np import functools +from scipy.optimize import curve_fit try: import cupy as cp @@ -1274,3 +1275,244 @@ def nesterov_gamma(zero_indexed_iter_num): return (1 - nesterov_lambda(one_indexed_iter_num)) / nesterov_lambda( one_indexed_iter_num + 1 ) + + + + + + +def regularize_probe_amp( + probe_init, + width_max_pixels = 2.0, + plot_polar = False, + plot_result = False, + figsize = (5,5), + ): + """ + Assume that the probe is centered in Fourier space. Note that I re-implemented the polar/cartesian transforms here for portability. + """ + + # Get probe intensity + probe_amp = np.abs(probe_init) + probe_int = probe_amp**2 + + # coordinates + xa,ya = np.meshgrid( + np.arange(probe_init.shape[0]), + np.arange(probe_init.shape[1]), + indexing = 'ij', + ) + + # Center of mass for probe intensity + int_total = np.sum(probe_int) + xy_center = ( + np.sum(probe_int * xa) / int_total, + np.sum(probe_int * ya) / int_total, + ) + + # Convert intensity to polar coordinates + polar_int = im_cart_to_polar( + probe_int, + xy_center = xy_center, + ) + + # Fit corrected probe intensity + radius = np.arange(polar_int.shape[1]) + + # estimate initial parameters + sub = polar_int > (np.max(polar_int)*0.5) + sig_0 = np.mean(polar_int[sub]) + rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) + width = np.minimum(1.0, width_max_pixels) + + # init + coefs_all = np.zeros((polar_int.shape[0],3)) + coefs_all[:,0] = sig_0 + coefs_all[:,1] = rad_0 + coefs_all[:,2] = width + + # bounds + lb = (0, 0, 0.5) + ub = (np.inf, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_fit = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_fit[a0,:] = step_model( + radius, + coefs_all[a0,:]) + + # Compute best-fit constant intensity inside probe + sig_0 = np.median(coefs_all[:,0]) + coefs_all[:,0] = sig_0 + lb = (sig_0-1e-8, 0, 0.5) + ub = (sig_0+1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_int_corr[a0,:] = step_model( + radius, + coefs_all[a0,:]) + + # Convert back to cartesian coordinates + int_corr = im_polar_to_cart( + polar_int_corr, + xy_size = probe_init.shape, + xy_center = xy_center, + ) + + # Assemble output probe + probe_corr = np.sqrt(np.maximum(int_corr,0)) \ + * np.exp(1j*np.angle(probe_init)) + + # plotting + if plot_result: + fig,ax = plt.subplots(figsize = (figsize[0]*2, figsize[1])) + ax.imshow( + np.hstack(( + probe_int, + int_corr, + )), + cmap = 'turbo', + ) + if plot_polar: + fig,ax = plt.subplots(figsize = figsize) + ax.imshow( + np.hstack(( + polar_int, + polar_fit, + polar_int_corr, + )), + cmap = 'turbo', + ) + + return probe_corr + + +def step_model(radius, *coefs): + coefs = np.squeeze(np.array(coefs)) + + sig_0 = coefs[0] + rad_0 = coefs[1] + width = coefs[2] + + return sig_0 * np.clip((rad_0 - radius) / width, 0, 1) + + +def im_cart_to_polar( + im_cart, + xy_center, + num_theta_bins = 180, + radius_max = None, + ): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + xa,ya = np.meshgrid( + np.arange(im_cart.shape[0]), + np.arange(im_cart.shape[1]), + indexing = 'ij', + ) + if radius_max is None: + radius_max = np.ceil(np.sqrt(np.sum( + np.array(im_cart.shape).astype('float')**2 + )) / 2.0).astype('int') + r = np.arange(radius_max) + t = np.linspace( + 0, + 2.0*np.pi, + num_theta_bins, + endpoint = False, + ) + ra,ta = np.meshgrid(r,t) + + # resampling coordinates + x = (ra * np.cos(ta) + xy_center[0]) + y = (ra * np.sin(ta) + xy_center[1]) + xf = np.floor(x).astype('int') + yf = np.floor(y).astype('int') + dx = x - xf + dy = y - yf + + # resample image + im_polar = \ + im_cart.ravel()[np.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode='clip', + )] * (1-dx) * (1-dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf+1, yf), + im_cart.shape, + mode='clip', + )] * ( dx) * (1-dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf, yf+1), + im_cart.shape, + mode='clip', + )] * (1-dx) * ( dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf+1, yf+1), + im_cart.shape, + mode='clip', + )] * ( dx) * ( dy) + + return im_polar + + +def im_polar_to_cart( + im_polar, + xy_size, + xy_center, + ): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + xa,ya = np.meshgrid( + np.arange(xy_size[0]) - xy_center[0], + np.arange(xy_size[1]) - xy_center[1], + indexing = 'ij', + ) + ra = np.sqrt(xa**2 + ya**2) + ta = np.arctan2(ya,xa) + t = np.linspace(0,2*np.pi,im_polar.shape[0],endpoint = False) + t_step = t[1] - t[0] + + # resampling coordinates + t_ind = ta / t_step + r_ind = ra.copy() + tf = np.floor(t_ind).astype('int') + rf = np.floor(r_ind).astype('int') + dt = t_ind - tf + dr = r_ind - rf + + # resample image + im_cart = im_polar.ravel()[np.ravel_multi_index( + (np.mod(tf, im_polar.shape[0]), rf), + im_polar.shape, + mode='clip', + )] + + return im_cart + From af6f030b56ff50f1edf84545c774685536177e48 Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:08:45 -0700 Subject: [PATCH 145/362] Adding docstrings --- py4DSTEM/process/phase/utils.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 8442b6cbc..112b1242c 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1284,12 +1284,40 @@ def nesterov_gamma(zero_indexed_iter_num): def regularize_probe_amp( probe_init, width_max_pixels = 2.0, - plot_polar = False, plot_result = False, + plot_polar = False, + cmap = 'turbo', figsize = (5,5), ): """ - Assume that the probe is centered in Fourier space. Note that I re-implemented the polar/cartesian transforms here for portability. + Assume that the probe is centered in Fourier space. Note we + re-implemented the polar/cartesian transforms here for portability. + + Parameters + -------- + probe_init: np.array + 2D complex image of the probe in Fourier space. + width_max_pixels: float + Maximum edge width of the probe in pixels. + plot_result: bool + Plot the input and output probes. + plot_polar: bool + Plot the polar transformed images: + 1 - initial probe + 2 - best fit of step model for each line + 3 - best fit enforcing constant intensity inside aperture + cmap: string + colormap of the plots. + figsize: tuple + size of the output figures. + (will be doubled along horizontal axis for cartesian images) + + Returns + -------- + probe_corr: np.array + 2D complex image of the corrected probe in Fourier space. + + """ # Get probe intensity From c41a93fe96666679167494a4e255f2798b36de0b Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:23:55 -0700 Subject: [PATCH 146/362] adding more options, cleaning up --- py4DSTEM/process/phase/utils.py | 64 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 112b1242c..29b76165c 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1284,6 +1284,8 @@ def nesterov_gamma(zero_indexed_iter_num): def regularize_probe_amp( probe_init, width_max_pixels = 2.0, + enforce_constant_intensity = True, + return_coefs = False, plot_result = False, plot_polar = False, cmap = 'turbo', @@ -1299,6 +1301,10 @@ def regularize_probe_amp( 2D complex image of the probe in Fourier space. width_max_pixels: float Maximum edge width of the probe in pixels. + enforce_constant_intensity: bool + Set to true to make intensity inside the aperture constant. + return_coefs: bool + If true, fitting coefficients will also be returned. plot_result: bool Plot the input and output probes. plot_polar: bool @@ -1316,6 +1322,9 @@ def regularize_probe_amp( -------- probe_corr: np.array 2D complex image of the corrected probe in Fourier space. + coefs_all: np.array (optional) + coefficients for the + """ @@ -1323,7 +1332,7 @@ def regularize_probe_amp( # Get probe intensity probe_amp = np.abs(probe_init) probe_int = probe_amp**2 - + # coordinates xa,ya = np.meshgrid( np.arange(probe_init.shape[0]), @@ -1351,7 +1360,7 @@ def regularize_probe_amp( sub = polar_int > (np.max(polar_int)*0.5) sig_0 = np.mean(polar_int[sub]) rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) - width = np.minimum(1.0, width_max_pixels) + width = width_max_pixels * 0.5 # init coefs_all = np.zeros((polar_int.shape[0],3)) @@ -1360,7 +1369,7 @@ def regularize_probe_amp( coefs_all[:,2] = width # bounds - lb = (0, 0, 0.5) + lb = (0.0, 0.0, 1e-4) ub = (np.inf, np.inf, width_max_pixels) # refine parameters, generate polar image @@ -1378,26 +1387,30 @@ def regularize_probe_amp( radius, coefs_all[a0,:]) - # Compute best-fit constant intensity inside probe - sig_0 = np.median(coefs_all[:,0]) - coefs_all[:,0] = sig_0 - lb = (sig_0-1e-8, 0, 0.5) - ub = (sig_0+1e-8, np.inf, width_max_pixels) + if enforce_constant_intensity: + # Compute best-fit constant intensity inside probe, update bounds + sig_0 = np.median(coefs_all[:,0]) + coefs_all[:,0] = sig_0 + lb = (sig_0-1e-8, 0.0, 1e-4) + ub = (sig_0+1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_int_corr[a0,:] = step_model( + radius, + coefs_all[a0,:]) - # refine parameters, generate polar image - polar_int_corr = np.zeros_like(polar_int) - for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_int_corr[a0,:] = step_model( - radius, - coefs_all[a0,:]) + else: + polar_int_corr = polar_fit # Convert back to cartesian coordinates int_corr = im_polar_to_cart( @@ -1431,7 +1444,10 @@ def regularize_probe_amp( cmap = 'turbo', ) - return probe_corr + if return_coefs: + return probe_corr, coefs_all + else: + return probe_corr def step_model(radius, *coefs): @@ -1441,7 +1457,7 @@ def step_model(radius, *coefs): rad_0 = coefs[1] width = coefs[2] - return sig_0 * np.clip((rad_0 - radius) / width, 0, 1) + return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) def im_cart_to_polar( From df7e9b42787638437593f531d9cf05468bd8ee42 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 9 Jul 2023 21:44:02 -0700 Subject: [PATCH 147/362] updated Colins code to work with corner-centered probes. will clean up and port to constraints tomorrow morning. --- py4DSTEM/process/phase/utils.py | 283 ++++++++++++++++---------------- 1 file changed, 140 insertions(+), 143 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 29b76165c..c92f0d38b 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -14,6 +14,7 @@ from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom +from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter # fmt: off @@ -1277,24 +1278,20 @@ def nesterov_gamma(zero_indexed_iter_num): ) - - - - def regularize_probe_amp( probe_init, - width_max_pixels = 2.0, - enforce_constant_intensity = True, - return_coefs = False, - plot_result = False, - plot_polar = False, - cmap = 'turbo', - figsize = (5,5), - ): + width_max_pixels=2.0, + enforce_constant_intensity=True, + return_coefs=False, + plot_result=False, + plot_polar=False, + cmap="turbo", + figsize=(5, 5), +): """ - Assume that the probe is centered in Fourier space. Note we + Assumes the probe is corner-centered in Fourier space. Note we re-implemented the polar/cartesian transforms here for portability. - + Parameters -------- probe_init: np.array @@ -1323,50 +1320,36 @@ def regularize_probe_amp( probe_corr: np.array 2D complex image of the corrected probe in Fourier space. coefs_all: np.array (optional) - coefficients for the - - - + coefficients for the """ # Get probe intensity probe_amp = np.abs(probe_init) probe_int = probe_amp**2 - # coordinates - xa,ya = np.meshgrid( - np.arange(probe_init.shape[0]), - np.arange(probe_init.shape[1]), - indexing = 'ij', - ) - # Center of mass for probe intensity - int_total = np.sum(probe_int) - xy_center = ( - np.sum(probe_int * xa) / int_total, - np.sum(probe_int * ya) / int_total, - ) + xy_center = get_CoM(probe_int, device="cpu", corner_centered=True) # Convert intensity to polar coordinates - polar_int = im_cart_to_polar( + polar_int = cartesian_to_polar_transform_2Ddata( probe_int, - xy_center = xy_center, - ) + xy_center=xy_center, + ) # Fit corrected probe intensity radius = np.arange(polar_int.shape[1]) # estimate initial parameters - sub = polar_int > (np.max(polar_int)*0.5) + sub = polar_int > (np.max(polar_int) * 0.5) sig_0 = np.mean(polar_int[sub]) - rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) + rad_0 = np.max(np.argwhere(np.sum(sub, axis=0))) width = width_max_pixels * 0.5 # init - coefs_all = np.zeros((polar_int.shape[0],3)) - coefs_all[:,0] = sig_0 - coefs_all[:,1] = rad_0 - coefs_all[:,2] = width + coefs_all = np.zeros((polar_int.shape[0], 3)) + coefs_all[:, 0] = sig_0 + coefs_all[:, 1] = rad_0 + coefs_all[:, 2] = width # bounds lb = (0.0, 0.0, 1e-4) @@ -1375,80 +1358,79 @@ def regularize_probe_amp( # refine parameters, generate polar image polar_fit = np.zeros_like(polar_int) for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_fit[a0,:] = step_model( + coefs_all[a0, :] = curve_fit( + step_model, radius, - coefs_all[a0,:]) + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_fit[a0, :] = step_model(radius, coefs_all[a0, :]) if enforce_constant_intensity: # Compute best-fit constant intensity inside probe, update bounds - sig_0 = np.median(coefs_all[:,0]) - coefs_all[:,0] = sig_0 - lb = (sig_0-1e-8, 0.0, 1e-4) - ub = (sig_0+1e-8, np.inf, width_max_pixels) + sig_0 = np.median(coefs_all[:, 0]) + coefs_all[:, 0] = sig_0 + lb = (sig_0 - 1e-8, 0.0, 1e-4) + ub = (sig_0 + 1e-8, np.inf, width_max_pixels) # refine parameters, generate polar image polar_int_corr = np.zeros_like(polar_int) for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_int_corr[a0,:] = step_model( + coefs_all[a0, :] = curve_fit( + step_model, radius, - coefs_all[a0,:]) + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_int_corr[a0, :] = step_model(radius, coefs_all[a0, :]) else: polar_int_corr = polar_fit # Convert back to cartesian coordinates - int_corr = im_polar_to_cart( + int_corr = polar_to_cartesian_transform_2Ddata( polar_int_corr, - xy_size = probe_init.shape, - xy_center = xy_center, - ) + xy_size=probe_init.shape, + xy_center=xy_center, + ) # Assemble output probe - probe_corr = np.sqrt(np.maximum(int_corr,0)) \ - * np.exp(1j*np.angle(probe_init)) + probe_corr = np.sqrt(np.maximum(int_corr, 0)) * np.exp(1j * np.angle(probe_init)) # plotting if plot_result: - fig,ax = plt.subplots(figsize = (figsize[0]*2, figsize[1])) + fig, ax = plt.subplots(figsize=(figsize[0] * 2, figsize[1])) ax.imshow( - np.hstack(( - probe_int, - int_corr, - )), - cmap = 'turbo', - ) + np.hstack( + ( + np.fft.fftshift(probe_int), + np.fft.fftshift(int_corr), + ) + ), + cmap="turbo", + ) if plot_polar: - fig,ax = plt.subplots(figsize = figsize) + fig, ax = plt.subplots(figsize=figsize) ax.imshow( - np.hstack(( - polar_int, - polar_fit, - polar_int_corr, - )), - cmap = 'turbo', - ) + np.hstack( + ( + polar_int, + polar_fit, + polar_int_corr, + ) + ), + cmap="turbo", + ) if return_coefs: return probe_corr, coefs_all else: return probe_corr - + def step_model(radius, *coefs): coefs = np.squeeze(np.array(coefs)) @@ -1460,103 +1442,118 @@ def step_model(radius, *coefs): return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) -def im_cart_to_polar( +def cartesian_to_polar_transform_2Ddata( im_cart, xy_center, - num_theta_bins = 180, - radius_max = None, - ): + num_theta_bins=180, + radius_max=None, +): """ Quick cartesian to polar conversion. """ # coordinates - xa,ya = np.meshgrid( - np.arange(im_cart.shape[0]), - np.arange(im_cart.shape[1]), - indexing = 'ij', - ) if radius_max is None: - radius_max = np.ceil(np.sqrt(np.sum( - np.array(im_cart.shape).astype('float')**2 - )) / 2.0).astype('int') + radius_max = np.min(np.array(im_cart.shape) // 2) + r = np.arange(radius_max) t = np.linspace( 0, - 2.0*np.pi, + 2.0 * np.pi, num_theta_bins, - endpoint = False, - ) - ra,ta = np.meshgrid(r,t) + endpoint=False, + ) + ra, ta = np.meshgrid(r, t) # resampling coordinates - x = (ra * np.cos(ta) + xy_center[0]) - y = (ra * np.sin(ta) + xy_center[1]) - xf = np.floor(x).astype('int') - yf = np.floor(y).astype('int') + x = ra * np.cos(ta) + xy_center[0] + y = ra * np.sin(ta) + xy_center[1] + + xf = np.floor(x).astype("int") + yf = np.floor(y).astype("int") dx = x - xf dy = y - yf # resample image - im_polar = \ - im_cart.ravel()[np.ravel_multi_index( - (xf, yf), - im_cart.shape, - mode='clip', - )] * (1-dx) * (1-dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf+1, yf), - im_cart.shape, - mode='clip', - )] * ( dx) * (1-dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf, yf+1), - im_cart.shape, - mode='clip', - )] * (1-dx) * ( dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf+1, yf+1), - im_cart.shape, - mode='clip', - )] * ( dx) * ( dy) + im_polar = ( + im_cart.ravel()[ + np.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode="wrap", + ) + ] + * (1 - dx) + * (1 - dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf + 1, yf), + im_cart.shape, + mode="wrap", + ) + ] + * (dx) + * (1 - dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf, yf + 1), + im_cart.shape, + mode="wrap", + ) + ] + * (1 - dx) + * (dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf + 1, yf + 1), + im_cart.shape, + mode="wrap", + ) + ] + * (dx) + * (dy) + ) return im_polar -def im_polar_to_cart( +def polar_to_cartesian_transform_2Ddata( im_polar, xy_size, xy_center, - ): +): """ Quick cartesian to polar conversion. """ # coordinates - xa,ya = np.meshgrid( - np.arange(xy_size[0]) - xy_center[0], - np.arange(xy_size[1]) - xy_center[1], - indexing = 'ij', - ) - ra = np.sqrt(xa**2 + ya**2) - ta = np.arctan2(ya,xa) - t = np.linspace(0,2*np.pi,im_polar.shape[0],endpoint = False) + sx, sy = xy_size + cx, cy = xy_center + + x = np.fft.fftfreq(sx, d=1 / sx) + y = np.fft.fftfreq(sy, d=1 / sy) + xa, ya = np.meshgrid(x, y, indexing="ij") + ra = np.hypot(xa - cx, ya - cy) + ta = np.arctan2(ya, xa) + + t = np.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) t_step = t[1] - t[0] # resampling coordinates t_ind = ta / t_step r_ind = ra.copy() - tf = np.floor(t_ind).astype('int') - rf = np.floor(r_ind).astype('int') + tf = np.floor(t_ind).astype("int") + rf = np.floor(r_ind).astype("int") dt = t_ind - tf dr = r_ind - rf # resample image - im_cart = im_polar.ravel()[np.ravel_multi_index( - (np.mod(tf, im_polar.shape[0]), rf), + im_cart = im_polar.ravel()[ + np.ravel_multi_index( + (tf, rf), im_polar.shape, - mode='clip', - )] + mode=("wrap", "clip"), + ) + ] return im_cart - From 28eb4938d89ca2ea794391f0aeeb57034e45a747 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 10 Jul 2023 16:39:55 -0400 Subject: [PATCH 148/362] braggvects masking fix --- py4DSTEM/braggvectors/braggvector_methods.py | 125 ++++++++++++++----- py4DSTEM/braggvectors/braggvectors.py | 11 ++ 2 files changed, 108 insertions(+), 28 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index c6289a253..fe3e86d70 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -2,6 +2,7 @@ import numpy as np from scipy.ndimage import gaussian_filter +from warnings import warn import inspect from emdfile import Array,Metadata @@ -896,52 +897,119 @@ def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, fl return strainmap + def mask_in_Q( + self, + mask, + update_inplace = False, + returncalc = True + ): + """ + Remove peaks which fall inside the diffraction shaped boolean array + `mask`, in raw (uncalibrated) peak positions. + + Parameters + ---------- + mask : 2d boolean array + The mask. Must be diffraction space shaped + update_inplace : bool + If False (default) copies this BraggVectors instance and + removes peaks from the copied instance. If True, removes + peaks from this instance. + returncalc : bool + Toggles returning the answer + Returns + ------- + bvects : BraggVectors + """ + # Copy peaks, if requested + if update_inplace: + v = self._v_uncal + else: + v = self._v_uncal.copy( name='_v_uncal' ) + + # Loop and remove masked peaks + for rx in range(v.shape[0]): + for ry in range(v.shape[1]): + p = v[rx,ry] + xs = np.round(p.data["qx"]).astype(int) + ys = np.round(p.data["qy"]).astype(int) + sub = mask[xs,ys] + p.remove(sub) + + # assign the return value + if update_inplace: + ans = self + else: + ans = self.copy( name=self.name+'_masked' ) + ans.set_raw_vectors( v ) + + # return + if returncalc: + return ans + else: + return + + # alias def get_masked_peaks( self, mask, update_inplace = False, returncalc = True): """ - Removes all bragg peaks which fall inside `mask` in the raw - (uncalibrated) positions. - - Args: - mask (bool): binary image where peaks will be deleted - update_inplace (bool): if True, removes peaks from this - BraggVectors instance. If False, returns a new - BraggVectors instance with the requested peaks removed - returncalc (bool): if True, return the BraggVectors + Alias for `mask_in_Q`. + """ + warn("`.get_masked_peaks` is deprecated and will be removed in a future version. Use `.mask_in_Q`") + return self.mask_in_Q( + mask = mask, + update_inplace = update_inplace, + returncalc = returncalc + ) - Returns: - (BraggVectors or None) + def mask_in_R( + self, + mask, + update_inplace = False, + returncalc = True + ): """ + Remove peaks which fall inside the real space shaped boolean array + `mask`. - # Copy peaks - v = self._v_uncal.copy( name='_v_uncal' ) + Parameters + ---------- + mask : 2d boolean array + The mask. Must be real space shaped + update_inplace : bool + If False (default) copies this BraggVectors instance and + removes peaks from the copied instance. If True, removes + peaks from this instance. + returncalc : bool + Toggles returning the answer - # Loop over all peaks + Returns + ------- + bvects : BraggVectors + """ + # Copy peaks, if requested + if update_inplace: + v = self._v_uncal + else: + v = self._v_uncal.copy( name='_v_uncal' ) + + # Loop and remove masked peaks for rx in range(v.shape[0]): for ry in range(v.shape[1]): - p = v.get_pointlist(rx,ry) - sub = mask.ravel()[np.ravel_multi_index(( - np.round(p.data["qx"]).astype('int'), - np.round(p.data["qy"]).astype('int')), - self.Qshape)] - p.remove(sub) + if mask[rx,ry]: + p = v[rx,ry] + p.remove(np.ones(len(p),dtype=bool)) - # if modifying this BraggVectors instance was requested + # assign the return value if update_inplace: - self._v_uncal = v ans = self - - # if a new instance was requested else: ans = self.copy( name=self.name+'_masked' ) - ans._v_uncal = v - - # re-calibrate - ans.calibrate() + ans.set_raw_vectors( v ) # return if returncalc: @@ -952,6 +1020,7 @@ def get_masked_peaks( + ######### END BraggVectorMethods CLASS ######## diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index d32997673..da8ffd3b2 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -101,6 +101,17 @@ def __init__( self._set_cal_vector_getter() + # set new raw vectors + def set_raw_vectors(self,x): + """ Given some PointListArray x of the correct shape, sets this to the raw vectors + """ + assert(isinstance(x,PointListArray)), f"Raw vectors must be set to a PointListArray, not type {type(x)}" + assert(x.shape == self.Rshape), "Shapes don't match!" + self._v_uncal = x + self._set_raw_vector_getter() + self._set_cal_vector_getter() + + # calibration state, vector getters @property From b93fa847f401edc23933c869a07a75787ea42e2d Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 10 Jul 2023 16:40:16 -0400 Subject: [PATCH 149/362] cmap deprecation fix --- py4DSTEM/visualize/show.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 20ed0be2b..3b9d99e43 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -553,7 +553,7 @@ def show( # Create colormap with mask_color for bad values - cm = copy(plt.colormaps.get_cmap(cmap)) + cm = copy(plt.get_cmap(cmap)) if mask_color=='empty': cm.set_bad(alpha=0) else: From bad5239727ca08bae5d6366ead7b0e73b8894ea1 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 10 Jul 2023 17:03:00 -0400 Subject: [PATCH 150/362] flaker edits --- py4DSTEM/braggvectors/__init__.py | 1 - py4DSTEM/braggvectors/braggvector_methods.py | 3 +- py4DSTEM/braggvectors/probe.py | 3 +- py4DSTEM/braggvectors/probe_gen_methods.py | 274 ------------------- py4DSTEM/datacube/virtualdiffraction.py | 4 +- py4DSTEM/datacube/virtualimage.py | 133 +++++---- 6 files changed, 71 insertions(+), 347 deletions(-) delete mode 100644 py4DSTEM/braggvectors/probe_gen_methods.py diff --git a/py4DSTEM/braggvectors/__init__.py b/py4DSTEM/braggvectors/__init__.py index ed09c04fc..030fe6358 100644 --- a/py4DSTEM/braggvectors/__init__.py +++ b/py4DSTEM/braggvectors/__init__.py @@ -3,7 +3,6 @@ from py4DSTEM.braggvectors.braggvector_methods import BraggVectorMap from py4DSTEM.braggvectors.diskdetection import * from py4DSTEM.braggvectors.probe import * -from py4DSTEM.braggvectors.probe_gen_methods import * #from .diskdetection_aiml import * #from .diskdetection_parallel_new import * diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index fe3e86d70..cf267b42d 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -5,8 +5,7 @@ from warnings import warn import inspect -from emdfile import Array,Metadata -from emdfile import _read_metadata +from emdfile import Array, Metadata, tqdmnd, _read_metadata from py4DSTEM.process.utils import get_CoM from py4DSTEM.datacube import VirtualImage diff --git a/py4DSTEM/braggvectors/probe.py b/py4DSTEM/braggvectors/probe.py index 3525e42be..32adfe1f2 100644 --- a/py4DSTEM/braggvectors/probe.py +++ b/py4DSTEM/braggvectors/probe.py @@ -2,6 +2,7 @@ import numpy as np from typing import Optional +from warnings import warn from py4DSTEM.data import DiffractionSlice, Data from py4DSTEM.process.calibration import get_probe_size @@ -425,7 +426,7 @@ def get_probe_kernel_flat( xCoM,yCoM = origin # Normalize - probe = self.probe/np.sum(probe) + probe = probe/np.sum(probe) # Shift center to corners of array probe_kernel = get_shifted_ar(probe, -xCoM, -yCoM, bilinear=bilinear) diff --git a/py4DSTEM/braggvectors/probe_gen_methods.py b/py4DSTEM/braggvectors/probe_gen_methods.py deleted file mode 100644 index a6afb1506..000000000 --- a/py4DSTEM/braggvectors/probe_gen_methods.py +++ /dev/null @@ -1,274 +0,0 @@ -# Functions for getting images of the vacuum probe - -import numpy as np -from scipy.ndimage import ( - binary_opening, binary_dilation, distance_transform_edt) - -from emdfile import tqdmnd -from py4DSTEM.datacube import DataCube -from py4DSTEM.braggvectors import Probe -from py4DSTEM.process.utils import get_shifted_ar, get_shift - - - - - -def get_vacuum_probe( - data, - **kwargs - ): - """ - Takes some data and computes a vacuum probe, using a method - selected based on the type and shape of `data`, and on other - arguments passed. In each case, points outside the center - disk are set to zero. - - Args: - data (variable): behavior and additional arguments depend on - the type of `data`. If `data` is a - - DataCube: computes a probe using all or some subset of - the diffraction patterns in the datacube, aligning and - averaging those patterns. The whole datacube is used - if the `ROI` argument is not passed. If `ROI` is - passed, uses a subset of diffraction patterns based on - the ROI argument's value, which may be a either an - R-space shaped boolean mask, or a 4-tuple representing - (Rxmin,Rxmax,Rymin,Rymax) of a rectangular region. - - 3D array: averages the stack with no alignment - - 2D array: uses this array as the probe. - - None: makes a synthetic probe. Additional required - arguments are - - radius (number): the probe radius - - width (number): the width of the region where - the probe intensity drops off from its maximum - to 0. - - Qshape (2 tuple): the shape of diffraction space - - Returns: - (Probe) a Probe instance - """ - - # select mode of operation - - if isinstance(data,DataCube): - mode = '4D' - elif isinstance(data,np.ndarray): - mode = str(data.ndim)+'D' - elif data is None: - mode = 'synth' - else: - er = f"invalid type {type(data)} for `data`." - er += f"must be in (DataCube,np.ndarray,None)" - raise Exception(er) - - if mode == '4D': - if 'ROI' in kwargs.keys(): - roi = kwargs['ROI'] - if isinstance(roi, np.ndarray): - mode = '4D_roi_mask' - else: - mode = '4D_roi_lims' - else: - mode = '4D_full' - - - - # choose and run a function - functions = { - '4D_full' : get_probe_from_vacuum_4Dscan, - '4D_roi_mask' : get_probe_from_4Dscan_ROI_mask, - '4D_roi_lims' : get_probe_from_4Dscan_ROI_lims, - '3D' : get_probe_from_vacuum_3Dstack, - '2D' : get_probe_from_vacuum_2Dimage, - 'synth' : get_probe_synthetic - } - fn = functions[mode] - if mode == 'synth': - probe = fn(**kwargs) - else: - probe = fn(data,**kwargs) - return probe - - - - - -def get_probe_from_vacuum_4Dscan( - datacube, - mask_threshold=0.2, - mask_expansion=12, - mask_opening=3, - verbose=False, - align=True - ): - """ - Averages all diffraction patterns in a datacube, assumed to be taken - over vacuum, to create and average vacuum probe. Optionally (default) - aligns the patterns. - - Values outisde the average probe are zeroed, using a binary mask determined - by the optional parameters mask_threshold, mask_expansion, and mask_opening. - An initial binary mask is created using a threshold of less than - mask_threshold times the maximal probe value. A morphological opening of - mask_opening pixels is performed to eliminate stray pixels (e.g. from - x-rays), followed by a dilation of mask_expansion pixels to ensure the - entire probe is captured. - - Args: - datacube (DataCube): a vacuum scan - mask_threshold (float): threshold determining mask which zeros values - outside of probe - mask_expansion (int): number of pixels by which the zeroing mask is - expanded to capture the full probe - mask_opening (int): size of binary opening used to eliminate stray - bright pixels - verbose (bool): if True, prints progress updates - align (bool): if True, aligns the probes before averaging - - Returns: - (ndarray of shape (datacube.Q_Nx,datacube.Q_Ny)): the average probe - """ - - probe = datacube.data[0,0,:,:] - for n in tqdmnd(range(1,datacube.R_N)): - Rx,Ry = np.unravel_index(n,datacube.data.shape[:2]) - curr_DP = datacube.data[Rx,Ry,:,:] - if verbose: - print(f"Shifting and averaging diffraction pattern {n} of {datacube.R_N}.") - if align: - xshift,yshift = get_shift(probe, curr_DP) - curr_DP = get_shifted_ar(curr_DP, xshift, yshift) - probe = probe*(n-1)/n + curr_DP/n - - mask = probe > np.max(probe)*mask_threshold - mask = binary_opening(mask, iterations=mask_opening) - mask = binary_dilation(mask, iterations=1) - mask = np.cos((np.pi/2)*np.minimum(distance_transform_edt(np.logical_not(mask)) / mask_expansion, 1))**2 - - return probe*mask - - - - -def get_probe_from_4Dscan_ROI_lims( - datacube, - ROI, - mask_threshold=0.2, - mask_expansion=12, - mask_opening=3, - verbose=False, - align=True - ): - """ - Averages all diffraction patterns within a specified ROI of a datacube to - create an average vacuum probe. Optionally (default) aligns the patterns. - - See documentation for get_average_probe_from_vacuum_scan for more detailed - discussion of the algorithm. - - Args: - datacube (DataCube): a vacuum scan - ROI (len 4 list or tuple): the limits (rx_min, rx_max, ry_min, ry_max) - of the selected region. - mask_threshold (float): threshold determining mask which zeros values - outside of probe - mask_expansion (int): number of pixels by which the zeroing mask is - expanded to capture the full probe - mask_opening (int): size of binary opening used to eliminate stray - bright pixels - verbose (bool): if True, prints progress updates - align (bool): if True, aligns the probes before averaging - DP_mask (array): array of same shape as diffraction pattern to mask - probes - - Returns: - (ndarray of shape (datacube.Q_Nx,datacube.Q_Ny)): the average probe - """ - assert len(ROI) == 4 - - datacube = DataCube( - data = datacube.data[ROI[0]:ROI[1],ROI[2]:ROI[3]] - ) - return get_probe_from_vacuum_4Dscan( - datacube, - mask_threshold = mask_threshold, - mask_expansion = mask_expansion, - mask_opening = mask_opening, - verbose = verbose, - align = align) - - - - -def get_probe_from_4Dscan_ROI_mask( - datacube, - ROI, - mask_threshold=0.2, - mask_expansion=12, - mask_opening=3, - verbose=False, - align=True, - DP_mask=1 - ): - """ - Averages all diffraction patterns within a specified ROI of a datacube to - create an average vacuum probe. Optionally (default) aligns the patterns. - - See documentation for get_average_probe_from_vacuum_scan for more detailed - discussion of the algorithm. - - Args: - datacube (DataCube): a vacuum scan - ROI (ndarray of dtype=bool and shape (datacube.R_Nx,datacube.R_Ny)): An - array of boolean variables shaped like the real space scan. Only scan - positions where ROI==True are used to create the average probe. - mask_threshold (float): threshold determining mask which zeros values - outside of probe - mask_expansion (int): number of pixels by which the zeroing mask is - expanded to capture the full probe - mask_opening (int): size of binary opening used to eliminate stray - bright pixels - verbose (bool): if True, prints progress updates - align (bool): if True, aligns the probes before averaging - DP_mask (array): array of same shape as diffraction pattern to mask - probes - - Returns: - (ndarray of shape (datacube.Q_Nx,datacube.Q_Ny)): the average probe - """ - assert ROI.shape==(datacube.R_Nx,datacube.R_Ny) - length = ROI.sum() - xy = np.vstack(np.nonzero(ROI)) - probe = datacube.data[xy[0,0],xy[1,0],:,:] - for n in tqdmnd(range(1,length)): - curr_DP = datacube.data[xy[0,n],xy[1,n],:,:] * DP_mask - if align: - xshift,yshift = get_shift(probe, curr_DP) - curr_DP = get_shifted_ar(curr_DP, xshift, yshift) - probe = probe*(n-1)/n + curr_DP/n - - mask = probe > np.max(probe)*mask_threshold - mask = binary_opening(mask, iterations=mask_opening) - mask = binary_dilation(mask, iterations=1) - mask = np.cos((np.pi/2)*np.minimum(distance_transform_edt(np.logical_not(mask)) / mask_expansion, 1))**2 - - return probe*mask - - - - - - - - - -# Probe templates can be generated from vacuum scans, from a selected ROI of a -# vacuum region of a scan, or synthetic probes. Ultimately the purpose is to -# generate a kernel for convolution with individual diffraction patterns to -# identify Bragg disks. Kernel generation will generally proceed in two steps, -# which will each correspond to a function call: first, obtaining or creating -# the diffraction pattern of a probe over vacuum, and second, turning the probe -# DP into a convolution kernel by shifting and normalizing. - - - diff --git a/py4DSTEM/datacube/virtualdiffraction.py b/py4DSTEM/datacube/virtualdiffraction.py index 9d1aaa4b7..f211a35a9 100644 --- a/py4DSTEM/datacube/virtualdiffraction.py +++ b/py4DSTEM/datacube/virtualdiffraction.py @@ -177,8 +177,8 @@ def get_virtual_diffraction( if not subpixel: # round shifts -> int - qx_shift = qshift.round().astype(int) - qy_shift = qshift.round().astype(int) + qx_shift = qx_shift.round().astype(int) + qy_shift = qy_shift.round().astype(int) # ...for boolean masks and unmasked if mask is None or mask.dtype==bool: diff --git a/py4DSTEM/datacube/virtualimage.py b/py4DSTEM/datacube/virtualimage.py index 7b7b315be..6731c0fd0 100644 --- a/py4DSTEM/datacube/virtualimage.py +++ b/py4DSTEM/datacube/virtualimage.py @@ -438,7 +438,7 @@ def position_detector( raise Exception("if `shift_center` is True then `data` must be the 3-tuple (DataCube,rx,ry)") # get shifts assert(self.calibration.get_origin_shift() is not None), "origin shifts need to be calibrated" - qx_shift,qy_shift = cal.get_origin_shift() + qx_shift,qy_shift = self.calibration.cal.get_origin_shift() qx_shift = int(np.round(qx_shift[rx,ry])) qy_shift = int(np.round(qy_shift[rx,ry])) mask = np.roll( @@ -619,72 +619,71 @@ def make_detector( - -# TODO - where should this go? - -def make_bragg_mask( - Qshape, - g1, - g2, - radius, - origin, - max_q, - return_sum = True, - **kwargs, - ): - ''' - Creates and returns a mask consisting of circular disks - about the points of a 2D lattice. - - Args: - Qshape (2 tuple): the shape of diffraction space - g1,g2 (len 2 array or tuple): the lattice vectors - radius (number): the disk radius - origin (len 2 array or tuple): the origin - max_q (nuumber): the maxima distance to tile to - return_sum (bool): if False, return a 3D array, where each - slice contains a single disk; if False, return a single - 2D masks of all disks - - Returns: - (2 or 3D array) the mask - ''' - nas = np.asarray - g1,g2,origin = nas(g1),nas(g2),nas(origin) - - # Get N,M, the maximum indices to tile out to - L1 = np.sqrt(np.sum(g1**2)) - H = int(max_q/L1) + 1 - L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) - K = int(max_q/L2) + 1 - - # Compute number of points - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - N += 1 - - #create mask - mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) - N = 0 - for h in range(-H,H+1): - for k in range(-K,K+1): - v = h*g1 + k*g2 - if np.sqrt(v.dot(v)) < max_q: - center = origin + v - mask[:,:,N] = make_detector( - Qshape, - mode = 'circle', - geometry = (center, radius), - ) - N += 1 - - - if return_sum: - mask = np.sum(mask, axis = 2) - return mask + # TODO where should this go? + def make_bragg_mask( + self, + Qshape, + g1, + g2, + radius, + origin, + max_q, + return_sum = True, + **kwargs, + ): + ''' + Creates and returns a mask consisting of circular disks + about the points of a 2D lattice. + + Args: + Qshape (2 tuple): the shape of diffraction space + g1,g2 (len 2 array or tuple): the lattice vectors + radius (number): the disk radius + origin (len 2 array or tuple): the origin + max_q (nuumber): the maxima distance to tile to + return_sum (bool): if False, return a 3D array, where each + slice contains a single disk; if False, return a single + 2D masks of all disks + + Returns: + (2 or 3D array) the mask + ''' + nas = np.asarray + g1,g2,origin = nas(g1),nas(g2),nas(origin) + + # Get N,M, the maximum indices to tile out to + L1 = np.sqrt(np.sum(g1**2)) + H = int(max_q/L1) + 1 + L2 = np.hypot(-g2[0]*g1[1],g2[1]*g1[0])/np.sqrt(np.sum(g1**2)) + K = int(max_q/L2) + 1 + + # Compute number of points + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + N += 1 + + #create mask + mask = np.zeros((Qshape[0], Qshape[1], N), dtype=bool) + N = 0 + for h in range(-H,H+1): + for k in range(-K,K+1): + v = h*g1 + k*g2 + if np.sqrt(v.dot(v)) < max_q: + center = origin + v + mask[:,:,N] = self.make_detector( + Qshape, + mode = 'circle', + geometry = (center, radius), + ) + N += 1 + + + if return_sum: + mask = np.sum(mask, axis = 2) + return mask From 4ae001dc4e15fcf6860042315cf6db388ab0ae79 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 10 Jul 2023 16:02:11 -0700 Subject: [PATCH 151/362] fix for WS2 --- py4DSTEM/process/diffraction/crystal_ACOM.py | 44 ++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index 4d02dcb0b..7039cb88c 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -767,6 +767,18 @@ def match_orientations( num_x=bragg_peaks_array.shape[0], num_y=bragg_peaks_array.shape[1], num_matches=num_matches_return) + + #check cal state + if bragg_peaks_array.calstate['ellipse'] == False: + ellipse = False + print('Warning: bragg peaks not elliptically calibrated') + else: + ellipse = True + if bragg_peaks_array.calstate['rotate'] == False: + rotate = False + print('Warning: bragg peaks not rotationally calibrated') + else: + rotate = True for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -774,9 +786,17 @@ def match_orientations( unit=" PointList", disable=not progress_bar, ): + vectors = bragg_peaks_array.get_vectors( + scan_x=rx, + scan_y=ry, + center=True, + ellipse=ellipse, + pixel=True, + rotate=rotate + ) orientation = self.match_single_pattern( - bragg_peaks_array.cal[rx, ry], + bragg_peaks=vectors, num_matches_return=num_matches_return, min_number_peaks=min_number_peaks, inversion_symmetry=inversion_symmetry, @@ -1639,6 +1659,18 @@ def calculate_strain( corr_kernel_size = self.orientation_kernel_size radius_max_2 = corr_kernel_size**2 + #check cal state + if bragg_peaks_array.calstate['ellipse'] == False: + ellipse = False + print('Warning: bragg peaks not elliptically calibrated') + else: + ellipse = True + if bragg_peaks_array.calstate['rotate'] == False: + rotate = False + print('Warning: bragg peaks not rotationally calibrated') + else: + rotate = True + # Loop over all probe positions for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -1647,7 +1679,14 @@ def calculate_strain( disable=not progress_bar, ): # Get bragg peaks from experiment and reference - p = bragg_peaks_array.cal[rx,ry] + p = bragg_peaks_array.get_vectors( + scan_x=rx, + scan_y=ry, + center=True, + ellipse=ellipse, + pixel=True, + rotate=rotate + ) if p.data.shape[0] >= min_num_peaks: p_ref = self.generate_diffraction_pattern( @@ -2071,4 +2110,3 @@ def symmetry_reduce_directions( # "-3m": ["fiber", [0, 0, 1], [90.0, 60.0]], # "-3m": ["fiber", [0, 0, 1], [180.0, 30.0]], - From f1e3dbe78905166af7ae53577a0c9d24a04ebad7 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 10 Jul 2023 17:13:35 -0700 Subject: [PATCH 152/362] small fixes --- py4DSTEM/braggvectors/braggvectors.py | 2 +- py4DSTEM/process/diffraction/crystal_ACOM.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index da8ffd3b2..af1078981 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -226,7 +226,7 @@ def setcal( if pixel: assert(c.get_Q_pixel_size() is not None), "Requested calibration not found" if rotate: - assert(c.get_RQ_rotflip() is not None), "Requested calibration not found" + assert(c.get_QR_rotflip() is not None), "Requested calibration not found" # set the calibrations self._calstate = { diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index 7039cb88c..686de7847 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -8,6 +8,8 @@ from py4DSTEM.process.diffraction.utils import Orientation, OrientationMap, axisEqual3D from py4DSTEM.process.utils import electron_wavelength_angstrom +from warnings import warn + from numpy.linalg import lstsq try: import cupy as cp @@ -771,12 +773,12 @@ def match_orientations( #check cal state if bragg_peaks_array.calstate['ellipse'] == False: ellipse = False - print('Warning: bragg peaks not elliptically calibrated') + warn('Warning: bragg peaks not elliptically calibrated') else: ellipse = True if bragg_peaks_array.calstate['rotate'] == False: rotate = False - print('Warning: bragg peaks not rotationally calibrated') + warn('bragg peaks not rotationally calibrated') else: rotate = True @@ -1662,12 +1664,12 @@ def calculate_strain( #check cal state if bragg_peaks_array.calstate['ellipse'] == False: ellipse = False - print('Warning: bragg peaks not elliptically calibrated') + warn('bragg peaks not elliptically calibrated') else: ellipse = True if bragg_peaks_array.calstate['rotate'] == False: rotate = False - print('Warning: bragg peaks not rotationally calibrated') + warn('bragg peaks not rotationally calibrated') else: rotate = True From 8215ff28ed7910bf0536e2a8d851a4e823c07646 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 10 Jul 2023 18:46:00 -0700 Subject: [PATCH 153/362] else changes --- py4DSTEM/io/filereaders/read_abTEM.py | 10 ++++++---- py4DSTEM/io/parsefiletype.py | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index cf6892d76..ce3b7774d 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -1,5 +1,5 @@ import h5py -from py4DSTEM.classes import DataCube, VirtualDiffraction, VirtualImage +from py4DSTEM.classes import DataCube, RealSlice, DiffractionSlice def read_abTEM( @@ -33,6 +33,8 @@ def read_abTEM( sampling = datasets["sampling"] units = datasets["units"] + assert len(data.shape) in (2, 4), "abtem reader supports only 4D and 2D data" + if len(data.shape) == 4: datacube = DataCube(data=data) @@ -57,9 +59,9 @@ def read_abTEM( return datacube - elif len(data.shape) == 2: + else: if units[0] == b"mrad": - diffraction = VirtualDiffraction(data=data) + diffraction = DiffractionSlice(data=data) if sampling[0] != sampling[1]: print( "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with x calibration" @@ -68,7 +70,7 @@ def read_abTEM( diffraction.calibration.set_Q_pixel_size(sampling[0]) return diffraction elif units[0] == b"\xc3\x85": - image = VirtualImage(data=data) + image = RealSlice(data=data) if sampling[0] != sampling[1]: print( "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index 8d5870944..9e081c916 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -30,6 +30,8 @@ def _parse_filetype(fp): elif _is_abTEM(fp): return "abTEM" + else: + raise Exception("not supported `h5` data type") elif fext in [ ".dm", From 47cfac46b3d24ff1bf56dfed6033b56327bd9325 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Mon, 10 Jul 2023 20:23:35 -0700 Subject: [PATCH 154/362] adding probe aperture constraint, aberration fitting. Only changed single-slice, will do rest of the classes tomorrow. --- .../iterative_ptychographic_constraints.py | 121 ++--- .../iterative_singleslice_ptychography.py | 105 +++-- py4DSTEM/process/phase/utils.py | 415 ++++++++++-------- 3 files changed, 304 insertions(+), 337 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 274e86f39..d3c5b34a9 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -3,6 +3,8 @@ array_slice, estimate_global_transformation_ransac, fft_shift, + regularize_probe_amplitude, + fit_aberration_surface, ) from py4DSTEM.process.utils import get_CoM @@ -338,67 +340,6 @@ def _probe_center_of_mass_constraint(self, current_probe): return shifted_probe - def _probe_radial_symmetrization_constraint_base( - self, - current_probe, - num_bins=None, - center=None, - ): - xp = self._xp - - sx, sy = current_probe.shape - - if center is None: - center = (0, 0) - - if num_bins is None: - num_bins = np.maximum(sx, sy) * 2 + 1 - - cx, cy = center - X = xp.fft.fftfreq(sx, d=1 / sx)[:, None] - Y = xp.fft.fftfreq(sy, d=1 / sy)[None] - r = xp.hypot(X - cx, Y - cy) - - rbin = (num_bins * r / r.max()).astype("int") - num = xp.bincount(rbin.ravel(), current_probe.ravel()) - denom = xp.bincount(rbin.ravel()) - denom[denom == 0] = 1 - - radial_mean = num / denom - - for r_bin, r_mean in enumerate(radial_mean): - if r_bin != 0.0: - current_probe[np.where(rbin == r_bin)] = r_mean - - return current_probe - - def _probe_radial_symmetrization_constraint( - self, - current_probe, - num_bins=None, - center=None, - ): - xp = self._xp - - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) - fourier_probe = xp.fft.fft2(current_probe) - - fourier_probe_real = fourier_probe.real.copy() - fourier_probe_imag = fourier_probe.imag.copy() - - fourier_probe_real = self._probe_radial_symmetrization_constraint_base( - fourier_probe_real, num_bins, center - ) - fourier_probe_imag = self._probe_radial_symmetrization_constraint_base( - fourier_probe_imag, num_bins, center - ) - - fourier_probe = fourier_probe_real + 1.0j * fourier_probe_imag - current_probe = xp.fft.ifft2(fourier_probe) - current_probe *= xp.sqrt(current_probe_sum / np.sum(np.abs(current_probe) ** 2)) - - return current_probe - def _probe_amplitude_constraint( self, current_probe, relative_radius, relative_width ): @@ -439,7 +380,10 @@ def _probe_amplitude_constraint( return updated_probe * normalization def _probe_fourier_amplitude_constraint( - self, current_probe, threshold, relative_width + self, + current_probe, + width_max_pixels, + enforce_constant_intensity, ): """ Ptychographic top-hat filtering of Fourier probe. @@ -460,27 +404,20 @@ def _probe_fourier_amplitude_constraint( Constrained probe estimate """ xp = self._xp - erf = self._erf + asnumpy = self._asnumpy current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft = xp.fft.fft2(current_probe) - current_probe_fft_amp = xp.abs(current_probe_fft) - threshold_px = xp.argmax( - current_probe_fft_amp < xp.max(current_probe_fft_amp) * threshold + updated_probe_fft, _, _, _ = regularize_probe_amplitude( + asnumpy(current_probe_fft), + width_max_pixels=width_max_pixels, + enforce_constant_intensity=enforce_constant_intensity, + corner_centered=True, ) - if threshold_px == 0: - return current_probe - - qx = xp.fft.fftfreq(current_probe.shape[0], 1) - qy = xp.fft.fftfreq(current_probe.shape[1], 1) - qya, qxa = xp.meshgrid(qy, qx) - qra = xp.sqrt(qxa**2 + qya**2) - threshold_px / current_probe.shape[0] - - sigma = np.sqrt(np.pi) / relative_width - tophat_mask = 0.5 * (1 - erf(sigma * qra / (1 - qra**2))) - updated_probe = xp.fft.ifft2(current_probe_fft * tophat_mask) + updated_probe_fft = xp.asarray(updated_probe_fft) + updated_probe = xp.fft.ifft2(updated_probe_fft) updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) normalization = xp.sqrt(current_probe_sum / updated_probe_sum) @@ -517,11 +454,11 @@ def _probe_aperture_constraint( return updated_probe * normalization - def _probe_residual_aberration_filtering_constraint( + def _probe_aberration_fitting_constraint( self, current_probe, - gaussian_filter_sigma, - fix_amplitude, + max_angular_order, + max_radial_order, ): """ Ptychographic probe smoothing constraint. @@ -543,24 +480,20 @@ def _probe_residual_aberration_filtering_constraint( """ xp = self._xp - gaussian_filter = self._gaussian_filter - known_aberrations_array = self._known_aberrations_array - gaussian_filter_sigma /= self._reciprocal_sampling[0] fourier_probe = xp.fft.fft2(current_probe) - if fix_amplitude: - fourier_probe_abs = xp.abs(fourier_probe) - - fourier_probe *= xp.conjugate(known_aberrations_array) - fourier_probe = gaussian_filter( - fourier_probe, gaussian_filter_sigma, mode="wrap" + fourier_probe_abs = xp.abs(fourier_probe) + sampling = self.sampling + + fitted_angle = fit_aberration_surface( + fourier_probe, + sampling, + max_angular_order, + max_radial_order, + xp=xp, ) - fourier_probe *= known_aberrations_array - - if fix_amplitude: - fourier_probe_angle = xp.angle(fourier_probe) - fourier_probe = fourier_probe_abs * xp.exp(1.0j * fourier_probe_angle) + fourier_probe = fourier_probe_abs * xp.exp(1.0j * fitted_angle) current_probe = xp.fft.ifft2(fourier_probe) return current_probe diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index bed535665..ed26cf8ad 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1000,15 +1000,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1038,14 +1038,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1053,10 +1051,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1122,31 +1121,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1179,20 +1176,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1246,19 +1243,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1593,12 +1589,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -1606,7 +1596,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index c92f0d38b..7f5287b3b 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -16,6 +16,7 @@ from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter +from skimage.restoration import unwrap_phase # fmt: off @@ -1278,19 +1279,143 @@ def nesterov_gamma(zero_indexed_iter_num): ) -def regularize_probe_amp( +def cartesian_to_polar_transform_2Ddata( + im_cart, + xy_center, + num_theta_bins=180, + radius_max=None, + corner_centered=False, + xp=np, +): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + if radius_max is None: + if corner_centered: + radius_max = np.min(np.array(im_cart.shape) // 2) + else: + radius_max = np.sqrt(np.sum(np.array(im_cart.shape) ** 2)) // 2 + + r = xp.arange(radius_max) + t = xp.linspace( + 0, + 2.0 * np.pi, + num_theta_bins, + endpoint=False, + ) + ra, ta = xp.meshgrid(r, t) + + # resampling coordinates + x = ra * xp.cos(ta) + xy_center[0] + y = ra * xp.sin(ta) + xy_center[1] + + xf = xp.floor(x).astype("int") + yf = xp.floor(y).astype("int") + dx = x - xf + dy = y - yf + + mode = "wrap" if corner_centered else "clip" + + # resample image + im_polar = ( + im_cart.ravel()[ + xp.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode=mode, + ) + ] + * (1 - dx) + * (1 - dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf + 1, yf), + im_cart.shape, + mode=mode, + ) + ] + * (dx) + * (1 - dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf, yf + 1), + im_cart.shape, + mode=mode, + ) + ] + * (1 - dx) + * (dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf + 1, yf + 1), + im_cart.shape, + mode=mode, + ) + ] + * (dx) + * (dy) + ) + + return im_polar + + +def polar_to_cartesian_transform_2Ddata( + im_polar, + xy_size, + xy_center, + corner_centered=False, + xp=np, +): + """ + Quick polar to cartesian conversion. + """ + + # coordinates + sx, sy = xy_size + cx, cy = xy_center + + if corner_centered: + x = xp.fft.fftfreq(sx, d=1 / sx) + y = xp.fft.fftfreq(sy, d=1 / sy) + else: + x = xp.arange(sx) + y = xp.arange(sy) + + xa, ya = xp.meshgrid(x, y, indexing="ij") + ra = xp.hypot(xa - cx, ya - cy) + ta = xp.arctan2(ya - cy, xa - cx) + + t = xp.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) + t_step = t[1] - t[0] + + # resampling coordinates + t_ind = ta / t_step + r_ind = ra.copy() + tf = xp.floor(t_ind).astype("int") + rf = xp.floor(r_ind).astype("int") + + # resample image + im_cart = im_polar.ravel()[ + xp.ravel_multi_index( + (tf, rf), + im_polar.shape, + mode=("wrap", "clip"), + ) + ] + + return im_cart + + +def regularize_probe_amplitude( probe_init, width_max_pixels=2.0, enforce_constant_intensity=True, - return_coefs=False, - plot_result=False, - plot_polar=False, - cmap="turbo", - figsize=(5, 5), + corner_centered=False, ): """ - Assumes the probe is corner-centered in Fourier space. Note we - re-implemented the polar/cartesian transforms here for portability. + Fits sigmoid for each angular direction. Parameters -------- @@ -1300,40 +1425,31 @@ def regularize_probe_amp( Maximum edge width of the probe in pixels. enforce_constant_intensity: bool Set to true to make intensity inside the aperture constant. - return_coefs: bool - If true, fitting coefficients will also be returned. - plot_result: bool - Plot the input and output probes. - plot_polar: bool - Plot the polar transformed images: - 1 - initial probe - 2 - best fit of step model for each line - 3 - best fit enforcing constant intensity inside aperture - cmap: string - colormap of the plots. - figsize: tuple - size of the output figures. - (will be doubled along horizontal axis for cartesian images) + corner_centered: bool + If True, the probe is assumed to be corner-centered Returns -------- - probe_corr: np.array + probe_corr: np.ndarray 2D complex image of the corrected probe in Fourier space. - coefs_all: np.array (optional) - coefficients for the + coefs_all: np.ndarray + coefficients for the sigmoid fits """ # Get probe intensity probe_amp = np.abs(probe_init) + probe_angle = np.angle(probe_init) probe_int = probe_amp**2 # Center of mass for probe intensity - xy_center = get_CoM(probe_int, device="cpu", corner_centered=True) + xy_center = get_CoM(probe_int, device="cpu", corner_centered=corner_centered) # Convert intensity to polar coordinates polar_int = cartesian_to_polar_transform_2Ddata( probe_int, xy_center=xy_center, + corner_centered=corner_centered, + xp=np, ) # Fit corrected probe intensity @@ -1346,6 +1462,9 @@ def regularize_probe_amp( width = width_max_pixels * 0.5 # init + def step_model(radius, sig_0, rad_0, width): + return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) + coefs_all = np.zeros((polar_int.shape[0], 3)) coefs_all[:, 0] = sig_0 coefs_all[:, 1] = rad_0 @@ -1366,194 +1485,114 @@ def regularize_probe_amp( xtol=1e-12, bounds=(lb, ub), )[0] - polar_fit[a0, :] = step_model(radius, coefs_all[a0, :]) - - if enforce_constant_intensity: - # Compute best-fit constant intensity inside probe, update bounds - sig_0 = np.median(coefs_all[:, 0]) - coefs_all[:, 0] = sig_0 - lb = (sig_0 - 1e-8, 0.0, 1e-4) - ub = (sig_0 + 1e-8, np.inf, width_max_pixels) - - # refine parameters, generate polar image - polar_int_corr = np.zeros_like(polar_int) - for a0 in range(polar_int.shape[0]): - coefs_all[a0, :] = curve_fit( - step_model, - radius, - polar_int[a0, :], - p0=coefs_all[a0, :], - xtol=1e-12, - bounds=(lb, ub), - )[0] - polar_int_corr[a0, :] = step_model(radius, coefs_all[a0, :]) + polar_fit[a0, :] = step_model(radius, *coefs_all[a0, :]) - else: - polar_int_corr = polar_fit + # Compute best-fit constant intensity inside probe, update bounds + sig_0 = np.median(coefs_all[:, 0]) + coefs_all[:, 0] = sig_0 + lb = (sig_0 - 1e-8, 0.0, 1e-4) + ub = (sig_0 + 1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0, :] = curve_fit( + step_model, + radius, + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) # Convert back to cartesian coordinates int_corr = polar_to_cartesian_transform_2Ddata( polar_int_corr, xy_size=probe_init.shape, xy_center=xy_center, + corner_centered=corner_centered, ) - # Assemble output probe - probe_corr = np.sqrt(np.maximum(int_corr, 0)) * np.exp(1j * np.angle(probe_init)) - - # plotting - if plot_result: - fig, ax = plt.subplots(figsize=(figsize[0] * 2, figsize[1])) - ax.imshow( - np.hstack( - ( - np.fft.fftshift(probe_int), - np.fft.fftshift(int_corr), - ) - ), - cmap="turbo", - ) - if plot_polar: - fig, ax = plt.subplots(figsize=figsize) - ax.imshow( - np.hstack( - ( - polar_int, - polar_fit, - polar_int_corr, - ) - ), - cmap="turbo", - ) - - if return_coefs: - return probe_corr, coefs_all - else: - return probe_corr - + amp_corr = np.sqrt(np.maximum(int_corr, 0)) -def step_model(radius, *coefs): - coefs = np.squeeze(np.array(coefs)) + # Assemble output probe + if not enforce_constant_intensity: + max_coeff = np.sqrt(coefs_all[:, 0]).max() + amp_corr = amp_corr / max_coeff * probe_amp - sig_0 = coefs[0] - rad_0 = coefs[1] - width = coefs[2] + probe_corr = amp_corr * np.exp(1j * probe_angle) - return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) + return probe_corr, polar_int, polar_int_corr, coefs_all -def cartesian_to_polar_transform_2Ddata( - im_cart, - xy_center, - num_theta_bins=180, - radius_max=None, +def aberrations_basis_function( + probe_size, + probe_sampling, + max_angular_order, + max_radial_order, + xp=np, ): - """ - Quick cartesian to polar conversion. - """ + """ """ + sx, sy = probe_size + dx, dy = probe_sampling + qx = xp.fft.fftfreq(sx, dx) + qy = xp.fft.fftfreq(sy, dy) - # coordinates - if radius_max is None: - radius_max = np.min(np.array(im_cart.shape) // 2) + qxa, qya = xp.meshgrid(qx, qy, indexing="ij") + q2 = qxa**2 + qya**2 + theta = xp.arctan2(qya, qxa) - r = np.arange(radius_max) - t = np.linspace( - 0, - 2.0 * np.pi, - num_theta_bins, - endpoint=False, - ) - ra, ta = np.meshgrid(r, t) + basis = [] + index = [] - # resampling coordinates - x = ra * np.cos(ta) + xy_center[0] - y = ra * np.sin(ta) + xy_center[1] + for n in range(max_angular_order + 1): + for m in range((max_radial_order - n) // 2 + 1): + basis.append((q2 ** (m + n / 2) * np.cos(n * theta))) + index.append((m, n, 0)) + if n > 0: + basis.append((q2 ** (m + n / 2) * np.sin(n * theta))) + index.append((m, n, 1)) - xf = np.floor(x).astype("int") - yf = np.floor(y).astype("int") - dx = x - xf - dy = y - yf + basis = xp.array(basis) - # resample image - im_polar = ( - im_cart.ravel()[ - np.ravel_multi_index( - (xf, yf), - im_cart.shape, - mode="wrap", - ) - ] - * (1 - dx) - * (1 - dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf + 1, yf), - im_cart.shape, - mode="wrap", - ) - ] - * (dx) - * (1 - dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf, yf + 1), - im_cart.shape, - mode="wrap", - ) - ] - * (1 - dx) - * (dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf + 1, yf + 1), - im_cart.shape, - mode="wrap", - ) - ] - * (dx) - * (dy) - ) - - return im_polar + return basis, index -def polar_to_cartesian_transform_2Ddata( - im_polar, - xy_size, - xy_center, +def fit_aberration_surface( + complex_probe, + probe_sampling, + max_angular_order, + max_radial_order, + seed=1, + xp=np, ): - """ - Quick cartesian to polar conversion. - """ + """ """ + probe_amp = xp.abs(complex_probe) + probe_angle = xp.angle(complex_probe) - # coordinates - sx, sy = xy_size - cx, cy = xy_center + if xp is np: + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True, seed=seed) + else: + unwrapped_angle = xp.asarray( + unwrap_phase(xp.asnumpy(probe_angle), wrap_around=True, seed=seed) + ) - x = np.fft.fftfreq(sx, d=1 / sx) - y = np.fft.fftfreq(sy, d=1 / sy) - xa, ya = np.meshgrid(x, y, indexing="ij") - ra = np.hypot(xa - cx, ya - cy) - ta = np.arctan2(ya, xa) + basis, _ = aberrations_basis_function( + complex_probe.shape, + probe_sampling, + max_angular_order, + max_radial_order, + xp=xp, + ) - t = np.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) - t_step = t[1] - t[0] + raveled_basis = basis.reshape((basis.shape[0], -1)) + raveled_weights = probe_amp.ravel() - # resampling coordinates - t_ind = ta / t_step - r_ind = ra.copy() - tf = np.floor(t_ind).astype("int") - rf = np.floor(r_ind).astype("int") - dt = t_ind - tf - dr = r_ind - rf + Aw = raveled_basis.T * raveled_weights[:, None] + bw = unwrapped_angle.ravel() * raveled_weights + coeff = xp.linalg.lstsq(Aw, bw, rcond=None)[0] - # resample image - im_cart = im_polar.ravel()[ - np.ravel_multi_index( - (tf, rf), - im_polar.shape, - mode=("wrap", "clip"), - ) - ] + fitted_angle = xp.tensordot(coeff, basis, axes=1) - return im_cart + return fitted_angle From 64c7a3a871c7917178394ee48ef7830fdea3f189 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 11 Jul 2023 05:57:06 -0700 Subject: [PATCH 155/362] fix for virtualimage/virtualdiffraction scalebar=True --- py4DSTEM/visualize/show.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 3b9d99e43..df6df1609 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -320,6 +320,9 @@ def show( if intensity_range is None: intensity_range = clipvals + if scalebar == True: + scalebar = {} + # plot a grid if `ar` is a list, or use multichannel functionality to make an RGBa image ar = ar[0] if (isinstance(ar,list) and len(ar) == 1) else ar if isinstance(ar,list): @@ -391,8 +394,6 @@ def show( # Output image for plotting ar = ar_rgb - if scalebar == True: - scalebar = {} # support for native data types elif not isinstance(ar,np.ndarray): From 5da30395a4dfa5aa3455a935595235a3689c596a Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 10:52:52 -0400 Subject: [PATCH 156/362] fix import paths w.r.t. new calpatch code --- py4DSTEM/io/filereaders/read_abTEM.py | 3 ++- py4DSTEM/io/filereaders/read_arina.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index ce3b7774d..d8d206914 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -1,5 +1,6 @@ import h5py -from py4DSTEM.classes import DataCube, RealSlice, DiffractionSlice +from py4DSTEM.datacube import DataCube +from py4DSTEM.data import RealSlice, DiffractionSlice def read_abTEM( diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index d42eb2803..2982d7f7f 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -1,7 +1,7 @@ import h5py import hdf5plugin import numpy as np -from py4DSTEM.classes import DataCube +from py4DSTEM.datacube import DataCube from py4DSTEM.preprocess.utils import bin2D From 08a3300b1863a0c65289fb71bda6cb1c06fbf4df Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 10:56:47 -0400 Subject: [PATCH 157/362] more import fixes --- py4DSTEM/io/read.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 979b2c216..746762434 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -8,6 +8,7 @@ import emdfile as emd import py4DSTEM.io.legacy as legacy from py4DSTEM.io.parsefiletype import _parse_filetype +from py4DSTEM.data import Data def read( @@ -94,7 +95,7 @@ def read( if verbose: print("Data was read from file. Adding calibration links...") # add calibration links - if isinstance(data,py4DSTEM.Data): + if isinstance(data,Data): with warnings.catch_warnings(): warnings.simplefilter('ignore') cal = data.calibration From 9a9d9a2892a845c1f993bb6bd991e864b94be3bc Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 10:58:38 -0400 Subject: [PATCH 158/362] more import fixes, all tests passing --- py4DSTEM/io/read.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 746762434..db3823fa6 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -99,7 +99,7 @@ def read( with warnings.catch_warnings(): warnings.simplefilter('ignore') cal = data.calibration - elif isinstance(data,py4DSTEM.Root): + elif isinstance(data,emd.Root): try: cal = data.metadata['calibration'] except KeyError: From 470006b0fde9cb7b2e51cb83d3434971a3991734 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 11:16:27 -0400 Subject: [PATCH 159/362] adds arina file download to test suite downloader --- py4DSTEM/io/google_drive_downloader.py | 57 ++++++++++++++++++++++++++ test/gettestdata.py | 21 +++++----- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index c8b410d47..69f4545f9 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -83,6 +83,50 @@ 'test_realslice_io.h5', '1siH80-eRJwG5R6AnU4vkoqGWByrrEz1y' ), + 'test_arina_master' : ( + 'STO-STEM_bench_20us_master.h5', + '1q_4IjFuWRkw5VM84NhxrNTdIq4563BOC' + ), + 'test_arina_01' : ( + 'STO-STEM_bench_20us_000001.h5', + '1_3Dbm22-hV58iffwK9x-3vqJUsEXZBFQ' + ), + 'test_arina_02' : ( + 'STO-STEM_bench_20us_000002.h5', + '1x29RzHLnCzP0qthLhA1kdlUQ09ENViR8' + ), + 'test_arina_03' : ( + 'STO-STEM_bench_20us_000003.h5', + '1qsbzdEVD8gt4DYKnpwjfoS_Mg4ggObAA' + ), + 'test_arina_04' : ( + 'STO-STEM_bench_20us_000004.h5', + '1Lcswld0Y9fNBk4-__C9iJbc854BuHq-h' + ), + 'test_arina_05' : ( + 'STO-STEM_bench_20us_000005.h5', + '13YTO2ABsTK5nObEr7RjOZYCV3sEk3gt9' + ), + 'test_arina_06' : ( + 'STO-STEM_bench_20us_000006.h5', + '1RywPXt6HRbCvjgjSuYFf60QHWlOPYXwy' + ), + 'test_arina_07' : ( + 'STO-STEM_bench_20us_000007.h5', + '1GRoBecCvAUeSIujzsPywv1vXKSIsNyoT' + ), + 'test_arina_08' : ( + 'STO-STEM_bench_20us_000008.h5', + '1sTFuuvgKbTjZz1lVUfkZbbTDTQmwqhuU' + ), + 'test_arina_09' : ( + 'STO-STEM_bench_20us_000009.h5', + '1JmBiMg16iMVfZ5wz8z_QqcNPVRym1Ezh' + ), + 'test_arina_10' : ( + 'STO-STEM_bench_20us_000010.h5', + '1_90xAfclNVwMWwQ-YKxNNwBbfR1nfHoB' + ), } # collections of files @@ -108,6 +152,19 @@ 'legacy_v0.14', 'test_realslice_io', ), + 'test_arina' : ( + 'test_arina_master', + 'test_arina_01', + 'test_arina_02', + 'test_arina_03', + 'test_arina_04', + 'test_arina_05', + 'test_arina_06', + 'test_arina_07', + 'test_arina_08', + 'test_arina_09', + 'test_arina_10', + ), 'test_braggvectors' : ( 'Au_sim', ) diff --git a/test/gettestdata.py b/test/gettestdata.py index 0b5608a7c..f6944e2df 100644 --- a/test/gettestdata.py +++ b/test/gettestdata.py @@ -19,7 +19,7 @@ data_options = [ 'tutorials', 'io', - 'basic' + 'basic', ] # Add arguments @@ -52,21 +52,22 @@ # Set data collection key if args.data == 'tutorials': - data = 'tutorials' + data = ['tutorials'] elif args.data == 'io': - data = 'test_io' + data = ['test_io','test_arina'] elif args.data == 'basic': - data = 'small_datacube' + data = ['small_datacube'] else: raise Exception(f"invalid data choice, {parser.data}") # Download data -download( - data, - destination = testpath, - overwrite = args.overwrite, - verbose = args.verbose -) +for d in data: + download( + d, + destination = testpath, + overwrite = args.overwrite, + verbose = args.verbose + ) # Always download the basic datacube if args.data != 'basic': From ee786aac9297260be970da164c90c26bca448097 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 11:18:20 -0400 Subject: [PATCH 160/362] closes if/else clause --- py4DSTEM/io/filereaders/read_abTEM.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index d8d206914..0e9cdc23e 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -70,7 +70,7 @@ def read_abTEM( diffraction.calibration.set_Q_pixel_units(units[0].decode("utf-8")) diffraction.calibration.set_Q_pixel_size(sampling[0]) return diffraction - elif units[0] == b"\xc3\x85": + else units[0] == b"\xc3\x85": image = RealSlice(data=data) if sampling[0] != sampling[1]: print( From f504924854ec940bea798964288d6019d1dce27a Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 11:21:07 -0400 Subject: [PATCH 161/362] closes if/else clause --- py4DSTEM/io/filereaders/read_abTEM.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index 0e9cdc23e..8191b57ae 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -70,7 +70,7 @@ def read_abTEM( diffraction.calibration.set_Q_pixel_units(units[0].decode("utf-8")) diffraction.calibration.set_Q_pixel_size(sampling[0]) return diffraction - else units[0] == b"\xc3\x85": + else: image = RealSlice(data=data) if sampling[0] != sampling[1]: print( From 01d9924ddf6cf475c2b4ed3186ef0902a28c3677 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 11:25:37 -0400 Subject: [PATCH 162/362] adds test_arina unit test --- test/test_nonnative_io/test_arina.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/test_nonnative_io/test_arina.py diff --git a/test/test_nonnative_io/test_arina.py b/test/test_nonnative_io/test_arina.py new file mode 100644 index 000000000..bf9bf8e73 --- /dev/null +++ b/test/test_nonnative_io/test_arina.py @@ -0,0 +1,19 @@ +import py4DSTEM +import emdfile +from os.path import join + + +# Set filepaths +filepath = join(py4DSTEM._TESTPATH, "test_arina/STO-STEM_bench_20us_master.h5") + + +def test_read_arina(): + + # read + data = py4DSTEM.import_file( filepath ) + + # check imported data + assert isinstance(data, emdfile.Array) + assert isinstance(data, py4DSTEM.DataCube) + + From 01092c32dc5e4b82a3886a8afd8bfb330e233b2a Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 11 Jul 2023 09:51:28 -0700 Subject: [PATCH 163/362] a bit of gpu cleaning --- .../process/phase/iterative_base_class.py | 3 --- py4DSTEM/process/phase/iterative_dpc.py | 11 +++++++- .../iterative_mixedstate_ptychography.py | 10 +++++++ .../iterative_multislice_ptychography.py | 10 +++++++ .../iterative_overlap_magnetic_tomography.py | 10 +++++++ .../phase/iterative_overlap_tomography.py | 10 +++++++ py4DSTEM/process/phase/iterative_parallax.py | 27 ++++++++++++++++++- .../iterative_simultaneous_ptychography.py | 10 +++++++ .../iterative_singleslice_ptychography.py | 10 +++++++ 9 files changed, 96 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 5888292c3..e48dc03ba 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -160,8 +160,6 @@ def _preprocess_datacube_and_vacuum_probe( "Datacube calibration can only handle uniform Q-sampling." ) - Q_pixel_size = datacube.calibration.get_Q_pixel_size() - if com_shifts is not None: com_shifts = ( com_shifts[0] * resampling_factor_x, @@ -279,7 +277,6 @@ def _extract_intensities_and_calibrations_from_datacube( """ # Copies intensities to device casting to float32 - xp = self._xp intensities = datacube.data self._grid_scan_shape = intensities.shape[:2] diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 4be160c64..71edd85bd 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -367,6 +367,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _forward( @@ -511,7 +516,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): constrained_object: np.ndarray Constrained object estimate """ - xp = self._xp gaussian_filter = self._gaussian_filter gaussian_filter_sigma /= self.sampling[0] @@ -814,6 +818,11 @@ def reconstruct( ] self.object_phase = asnumpy(self._object_phase) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration( diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index d4e2e5346..c80ec1062 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -574,6 +574,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -1727,6 +1732,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index d477da8ce..66c943ec6 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -673,6 +673,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -2149,6 +2154,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 7c88931a5..c3f1e8fb7 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -905,6 +905,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection( @@ -2540,6 +2545,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _crop_rotate_object_manually( diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6b0a16e2e..c8f4487b5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -817,6 +817,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -2261,6 +2266,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _crop_rotate_object_manually( diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 576342631..d55d5c353 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -172,7 +172,6 @@ def preprocess( require_calibrations=True, ) self._intensities = xp.asarray(self._intensities, dtype=xp.float32) - # make sure mean diffraction pattern is shaped correctly if (self._dp_mean.shape[0] != self._intensities.shape[2]) or ( self._dp_mean.shape[1] != self._intensities.shape[3] @@ -377,6 +376,12 @@ def preprocess( ax.set_title("Average Bright Field Image") self._preprocessed = True + + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def tune_angle_and_defocus( @@ -827,6 +832,11 @@ def reconstruct( self.recon_BF = asnumpy(self._recon_BF) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def aberration_fit( @@ -876,6 +886,11 @@ def aberration_fit( ) / 2.0 # factor /2 for A1 astigmatism? /4? self.aberration_A1y = (m_aberration[1, 0] + m_aberration[0, 1]) / 2.0 + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + # Print results if self._verbose: print( @@ -1061,6 +1076,11 @@ def aberration_correct( self._recon_phase_corrected = xp.real(xp.fft.ifft2(im_fft_corr)) self.recon_phase_corrected = asnumpy(self._recon_phase_corrected) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + # plotting if plot_corrected_phase: figsize = kwargs.pop("figsize", (6, 6)) @@ -1219,6 +1239,11 @@ def depth_section( ax.set_yticks([]) ax.set_title(f"Depth section: {dz}A") + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return stack_depth def _crop_padded_object( diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 545900634..8904012b2 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -814,6 +814,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _warmup_overlap_projection(self, current_object, current_probe): @@ -2926,6 +2931,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index ed26cf8ad..12604a287 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -542,6 +542,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -1633,6 +1638,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( From 9e66b7a7d9fa77b878ad35bafc2eb2b3c55dbb86 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 13:27:17 -0400 Subject: [PATCH 164/362] rm deprecated virtualdiffraction.py --- py4DSTEM/process/__init__.py | 1 - py4DSTEM/process/virtualdiffraction.py | 223 ------------------------- 2 files changed, 224 deletions(-) delete mode 100644 py4DSTEM/process/virtualdiffraction.py diff --git a/py4DSTEM/process/__init__.py b/py4DSTEM/process/__init__.py index 833466cd3..76ad38d47 100644 --- a/py4DSTEM/process/__init__.py +++ b/py4DSTEM/process/__init__.py @@ -1,6 +1,5 @@ from py4DSTEM.process.polar import PolarDatacube -from py4DSTEM.process import virtualdiffraction from py4DSTEM.process import latticevectors from py4DSTEM.process import phase from py4DSTEM.process import calibration diff --git a/py4DSTEM/process/virtualdiffraction.py b/py4DSTEM/process/virtualdiffraction.py deleted file mode 100644 index ba31b778a..000000000 --- a/py4DSTEM/process/virtualdiffraction.py +++ /dev/null @@ -1,223 +0,0 @@ -# Functions for generating diffraction images - -import numpy as np -from emdfile import tqdmnd - -def get_virtual_diffraction( - datacube, - method, - mode = None, - geometry = None, - calibrated = False, - shift_center = False, - verbose = True, - return_mask = False, -): - ''' - Function to calculate virtual diffraction - - Args: - datacube (Datacube) : datacube class object which stores 4D-dataset - needed for calculation - method (str) : defines method used for diffraction pattern, options are - 'mean', 'median', and 'max' - mode (str) : defines mode for selecting area in real space to use for - virtual diffraction. The default is None, which means no - geometry will be applied and the whole datacube will be used - for the calculation. Options: - - 'point' uses singular point as detector - - 'circle' or 'circular' uses round detector, like bright field - - 'annular' or 'annulus' uses annular detector, like dark field - - 'rectangle', 'square', 'rectangular', uses rectangular detector - - 'mask' flexible detector, any 2D array - geometry (variable) : valid entries are determined by the `mode`, values - in pixels argument, as follows. The default is None, which means no - geometry will be applied and the whole datacube will be used for the - calculation. If mode is None the geometry will not be applied. - - 'point': 2-tuple, (rx,ry), - qx and qy are each single float or int to define center - - 'circle' or 'circular': nested 2-tuple, ((rx,ry),radius), - qx, qy and radius, are each single float or int - - 'annular' or 'annulus': nested 2-tuple, ((rx,ry),(radius_i,radius_o)), - qx, qy, radius_i, and radius_o are each single float or integer - - 'rectangle', 'square', 'rectangular': 4-tuple, (xmin,xmax,ymin,ymax) - - `mask`: flexible detector, any boolean or floating point 2D array with - the same shape as datacube.Rshape - calibrated (bool): if True, geometry is specified in units of 'A' instead - of pixels. The datacube's calibrations must have its `"R_pixel_units"` - parameter set to "A". If mode is None the geometry and calibration will - not be applied. - shift_center (bool): if True, the difraction pattern is shifted to account - for beam shift or the changing of the origin through the scan. The - datacube's calibration['origin'] parameter must be set Only 'max' and - 'mean' supported for this option. - verbose (bool): if True, show progress bar - return_mask (bool): if False (default) returns a virtual image as usual. - If True, does *not* generate or return a virtual image, instead - returning the mask that would be used in virtual diffraction computation. - - Returns: - (2D array): the diffraction image - ''' - - assert method in ('max', 'median', 'mean'),\ - 'check doc strings for supported types' - - #create mask - if mode is not None: - use_all_points = False - - from py4DSTEM.process.virtualimage import make_detector - assert mode in ('point', 'circle', 'circular', 'annulus', 'annular', 'rectangle', 'square', 'rectangular', 'mask'),\ - 'check doc strings for supported modes' - g = geometry - - if calibrated == True: - assert datacube.calibration['R_pixel_units'] == 'A', \ - 'check datacube.calibration. datacube must be calibrated in A to use `calibrated=True`' - - unit_conversion = datacube.calibration['R_pixel_size'] - if mode == 'point': - g = (g[0]/unit_conversion, g[1]/unit_conversion) - if mode in('circle', 'circular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1]/unit_conversion)) - if mode in('annulus', 'annular'): - g = ((g[0][0]/unit_conversion, g[0][1]/unit_conversion), - (g[1][0]/unit_conversion, g[1][1]/unit_conversion)) - if mode in('rectangle', 'square', 'rectangular') : - g = (g[0]/unit_conversion, g[1]/unit_conversion, - g[2]/unit_conversion, g[3]/unit_conversion) - - # Get mask - mask = make_detector(datacube.Rshape, mode, g) - - # Determine if mask is boolean and if so, vectorize - if mask.dtype == bool: - mask_is_boolean = True - mask_indices = np.nonzero(mask) - else: - mask_is_boolean = False - - #if no mask - else: - mask = np.ones(datacube.Rshape, dtype=bool) - mask_indices = np.nonzero(mask) - use_all_points = True - mask_is_boolean = False - - # if return_mask is True, skip computation - if return_mask == True: - return mask - - # Calculate diffracton pattern... - - # ...with no center shifting - if shift_center == False: - - # ...for the whole pattern - if use_all_points: - if method == 'mean': - virtual_diffraction = np.mean(datacube.data, axis=(0,1)) - elif method == 'max': - virtual_diffraction = np.max(datacube.data, axis=(0,1)) - else: - virtual_diffraction = np.median(datacube.data, axis=(0,1)) - - # ...for boolean masks - elif mask_is_boolean: - if method == 'mean': - virtual_diffraction = np.mean(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) - elif method == 'max': - virtual_diffraction = np.max(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) - else: - virtual_diffraction = np.median(datacube.data[mask_indices[0],mask_indices[1],:,:], axis=0) - - # ...for floating point masks - else: - if mask.dtype == 'complex': - virtual_diffraction = np.zeros(datacube.Qshape, dtype = 'complex') - else: - virtual_diffraction = np.zeros(datacube.Qshape) - for qx,qy in tqdmnd( - datacube.Q_Nx, - datacube.Q_Ny, - disable = not verbose, - ): - if method == 'mean': - virtual_diffraction[qx,qy] = np.sum( np.squeeze(datacube.data[:,:,qx,qy])*mask ) - elif method == 'max': - virtual_diffraction[qx,qy] = np.max( np.squeeze(datacube.data[:,:,qx,qy])*mask ) - elif method == 'median': - virtual_diffraction[qx,qy] = np.median( np.squeeze(datacube.data[:,:,qx,qy])*mask ) - - # norm by weighting term for means - if method == 'mean' and not use_all_points: - virtual_diffraction /= np.sum(mask) - - # ...with center shifting - else: - assert method in ('max', 'mean'),\ - "only 'mean' and 'max' are supported for center-shifted virtual diffraction" - - # Get calibration metadata - assert datacube.calibration.get_origin(), "origin needs to be calibrated" - x0, y0 = datacube.calibration.get_origin() - x0_mean, y0_mean = datacube.calibration.get_origin_mean() - - # get shifts - qx_shift = (x0_mean-x0).round().astype(int) - qy_shift = (y0_mean-y0).round().astype(int) - - - # compute... - - # ...for boolean masks / whole datacubes - if mask_is_boolean or use_all_points: - virtual_diffraction = np.zeros(datacube.Qshape) - for rx,ry in zip(mask_indices[0],mask_indices[1]): - # get shifted DP - DP = np.roll( - datacube.data[rx,ry, :,:,], - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1), - ) - # compute - if method == 'mean': - virtual_diffraction += DP - elif method == 'max': - virtual_diffraction = np.maximum(virtual_diffraction, DP) - if method == 'mean': - virtual_diffraction /= len(mask_indices[0]) - - # ...for floating point masks - else: - if mask.dtype == 'complex': - virtual_diffraction = np.zeros(datacube.Qshape, dtype = 'complex') - else: - virtual_diffraction = np.zeros(datacube.Qshape) - for rx,ry in tqdmnd( - datacube.R_Nx, - datacube.R_Ny, - disable = not verbose, - ): - # get shifted DP - DP = np.roll( - datacube.data[rx,ry, :,:,], - (qx_shift[rx,ry], qy_shift[rx,ry]), - axis=(0,1), - ) - # compute - w = mask[rx,ry] - if w > 0: - if method == 'mean': - virtual_diffraction += DP*w - elif method == 'max': - virtual_diffraction = np.maximum(virtual_diffraction, DP*w) - if method == 'mean': - virtual_diffraction /= np.sum(mask) - - # return - return virtual_diffraction - - From e891c077af34ee65afd0841d718d981eb65896b5 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 11:09:24 -0700 Subject: [PATCH 165/362] removing unnecessary self._xp --- py4DSTEM/process/phase/iterative_dpc.py | 2 -- py4DSTEM/process/phase/iterative_mixedstate_ptychography.py | 2 -- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 2 -- .../process/phase/iterative_overlap_magnetic_tomography.py | 2 -- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 -- py4DSTEM/process/phase/iterative_parallax.py | 4 ---- py4DSTEM/process/phase/iterative_simultaneous_ptychography.py | 2 -- py4DSTEM/process/phase/iterative_singleslice_ptychography.py | 2 -- 8 files changed, 18 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 71edd85bd..dc0df2ce6 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -368,7 +368,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -819,7 +818,6 @@ def reconstruct( self.object_phase = asnumpy(self._object_phase) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index c80ec1062..69b2d8c45 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -575,7 +575,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1733,7 +1732,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 66c943ec6..4706decf9 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -674,7 +674,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2155,7 +2154,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index c3f1e8fb7..099d26bcb 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -906,7 +906,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2546,7 +2545,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index c8f4487b5..b5a3f71fa 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -818,7 +818,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2267,7 +2266,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index d55d5c353..80cdd8cd8 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -378,7 +378,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -833,7 +832,6 @@ def reconstruct( self.recon_BF = asnumpy(self._recon_BF) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -887,7 +885,6 @@ def aberration_fit( self.aberration_A1y = (m_aberration[1, 0] + m_aberration[0, 1]) / 2.0 if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1077,7 +1074,6 @@ def aberration_correct( self.recon_phase_corrected = asnumpy(self._recon_phase_corrected) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 8904012b2..cf243192e 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -815,7 +815,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2932,7 +2931,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 12604a287..2d5744e28 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -543,7 +543,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1639,7 +1638,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() From e3dbcb73a2350a54a23d10fae464fbf98ae803cc Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 11 Jul 2023 11:58:31 -0700 Subject: [PATCH 166/362] reformatting --- py4DSTEM/io/filereaders/read_abTEM.py | 2 +- py4DSTEM/io/read.py | 51 ++++++++++++++------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index 8191b57ae..57c839c75 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -1,6 +1,6 @@ import h5py +from py4DSTEM.data import DiffractionSlice, RealSlice from py4DSTEM.datacube import DataCube -from py4DSTEM.data import RealSlice, DiffractionSlice def read_abTEM( diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index db3823fa6..bab555eaf 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -1,14 +1,14 @@ # Reader for native files +import warnings from os.path import exists from pathlib import Path -from typing import Optional,Union -import warnings +from typing import Optional, Union import emdfile as emd import py4DSTEM.io.legacy as legacy -from py4DSTEM.io.parsefiletype import _parse_filetype from py4DSTEM.data import Data +from py4DSTEM.io.parsefiletype import _parse_filetype def read( @@ -75,48 +75,50 @@ def read( # support older `root` input if datapath is None: - if 'root' in kwargs: - datapath = kwargs['root'] + if "root" in kwargs: + datapath = kwargs["root"] # EMD 1.0 formatted files (py4DSTEM v0.14+) if filetype == "emd": # check version version = emd._get_EMD_version(filepath) - if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") - assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" + if verbose: + print( + f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading..." + ) + assert emd._version_is_geq( + version, (1, 0, 0) + ), f"EMD version {version} detected. Expected version >= 1.0.0" # read - data = emd.read( - filepath, - emdpath = datapath, - tree = tree - ) - if verbose: print("Data was read from file. Adding calibration links...") + data = emd.read(filepath, emdpath=datapath, tree=tree) + if verbose: + print("Data was read from file. Adding calibration links...") # add calibration links - if isinstance(data,Data): + if isinstance(data, Data): with warnings.catch_warnings(): - warnings.simplefilter('ignore') + warnings.simplefilter("ignore") cal = data.calibration - elif isinstance(data,emd.Root): + elif isinstance(data, emd.Root): try: - cal = data.metadata['calibration'] + cal = data.metadata["calibration"] except KeyError: cal = None else: cal = None if cal is not None: try: - root_treepath = cal['_root_treepath'] - target_paths = cal['_target_paths'] - del(cal._params['_target_paths']) + root_treepath = cal["_root_treepath"] + target_paths = cal["_target_paths"] + del cal._params["_target_paths"] for p in target_paths: try: - p = p.replace(root_treepath,'') + p = p.replace(root_treepath, "") d = data.root.tree(p) - cal.register_target( d ) - if hasattr(d,'setcal'): + cal.register_target(d) + if hasattr(d, "setcal"): d.setcal() except AssertionError: pass @@ -125,7 +127,8 @@ def read( cal.calibrate() # return - if verbose: print("Done.") + if verbose: + print("Done.") return data # legacy py4DSTEM files (v <= 0.13) From 9dd77124111cff4d651d10caa8c855b8a2c55822 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 15:03:33 -0400 Subject: [PATCH 167/362] adds new strain class, instantiation tests --- py4DSTEM/__init__.py | 3 + py4DSTEM/braggvectors/braggvector_methods.py | 2 +- py4DSTEM/braggvectors/probe.py | 13 +++- py4DSTEM/process/__init__.py | 1 + py4DSTEM/process/strain.py | 82 ++++++++++++++++++++ test/test_strain.py | 70 +++++++++++++++++ 6 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 py4DSTEM/process/strain.py create mode 100644 test/test_strain.py diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index 17d255d92..21409c101 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -59,6 +59,9 @@ BraggVectorMap, ) +# strain +from py4DSTEM.process import StrainMap + # TODO - crystal # TODO - ptycho # TODO - others diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index cf267b42d..e04a7558a 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -6,7 +6,6 @@ import inspect from emdfile import Array, Metadata, tqdmnd, _read_metadata -from py4DSTEM.process.utils import get_CoM from py4DSTEM.datacube import VirtualImage @@ -358,6 +357,7 @@ def measure_origin( np.argmax(gaussian_filter(bvm, 10)), (Q_Nx, Q_Ny) ) else: + from py4DSTEM.process.utils import get_CoM x0, y0 = get_CoM(bvm) else: x0, y0 = center_guess diff --git a/py4DSTEM/braggvectors/probe.py b/py4DSTEM/braggvectors/probe.py index 32adfe1f2..9195d06bd 100644 --- a/py4DSTEM/braggvectors/probe.py +++ b/py4DSTEM/braggvectors/probe.py @@ -5,8 +5,6 @@ from warnings import warn from py4DSTEM.data import DiffractionSlice, Data -from py4DSTEM.process.calibration import get_probe_size -from py4DSTEM.process.utils import get_CoM, get_shifted_ar from scipy.ndimage import ( binary_opening, binary_dilation, distance_transform_edt) @@ -245,6 +243,8 @@ def measure_disk( r, x0, y0 : (3-tuple) the radius and origin """ + from py4DSTEM.process.utils import get_CoM + # set the image im = self.probe if data is None else data @@ -417,10 +417,13 @@ def get_probe_kernel_flat( the cross-correlation kernel corresponding to the probe, in real space """ + from py4DSTEM.process.utils import get_shifted_ar + Q_Nx, Q_Ny = probe.shape # Get CoM if origin is None: + from py4DSTEM.process.calibration import get_probe_size _,xCoM,yCoM = get_probe_size(probe) else: xCoM,yCoM = origin @@ -466,10 +469,13 @@ def get_probe_kernel_edge_gaussian( kernel : ndarray the cross-correlation kernel """ + from py4DSTEM.process.utils import get_shifted_ar + Q_Nx, Q_Ny = probe.shape # Get CoM if origin is None: + from py4DSTEM.process.calibration import get_probe_size _,xCoM,yCoM = get_probe_size(probe) else: xCoM,yCoM = origin @@ -526,6 +532,8 @@ def get_probe_kernel_edge_sigmoid( kernel : 2d array the cross-correlation kernel """ + from py4DSTEM.process.utils import get_shifted_ar + # parse inputs if isinstance(probe,Probe): probe = probe.probe @@ -537,6 +545,7 @@ def get_probe_kernel_edge_sigmoid( # Get CoM if origin is None: + from py4DSTEM.process.calibration import get_probe_size _,xCoM,yCoM = get_probe_size(probe) else: xCoM,yCoM = origin diff --git a/py4DSTEM/process/__init__.py b/py4DSTEM/process/__init__.py index 76ad38d47..73088068b 100644 --- a/py4DSTEM/process/__init__.py +++ b/py4DSTEM/process/__init__.py @@ -1,4 +1,5 @@ from py4DSTEM.process.polar import PolarDatacube +from py4DSTEM.process.strain import StrainMap from py4DSTEM.process import latticevectors from py4DSTEM.process import phase diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py new file mode 100644 index 000000000..159bc3265 --- /dev/null +++ b/py4DSTEM/process/strain.py @@ -0,0 +1,82 @@ +# Defines the Strain class + +import numpy as np +from typing import Optional +from py4DSTEM.data import RealSlice, Data +from py4DSTEM.braggvectors import BraggVectors + + + +class StrainMap(RealSlice,Data): + """ + Stores strain map. + + TODO add docs + + """ + + def __init__( + self, + braggvectors: BraggVectors, + name: Optional[str] = 'strainmap' + ): + """ + TODO + """ + # set up braggvectors + self.braggvectors = braggvectors + # TODO - how to handle changes to braggvectors + # TODO - ellipse cal or no? + + # set up data + data = np.empty(( + self.braggvectors.Rshape[0], + self.braggvectors.Rshape[1], + 6 + )) + + # initialize as a RealSlice + RealSlice.__init__( + self, + name = name, + data = data, + slicelabels = [ + 'exx', + 'eyy', + 'exy', + 'theta', + 'mask', + 'error' + ] + ) + + + # braggvector properties + + @property + def braggvectors(self): + return self._braggvectors + @braggvectors.setter + def braggvectors(self,x): + assert(isinstance(x,BraggVectors)), f".braggvectors must be BraggVectors, not type {type(x)}" + assert(x.calibration.origin is not None), f"braggvectors must have a calibrated origin" + self._braggvectors = x + + + # TODO - copy method + + # read + @classmethod + def _get_constructor_args(cls,group): + """ + Returns a dictionary of args/values to pass to the class constructor + """ + ar_constr_args = RealSlice._get_constructor_args(group) + args = { + 'data' : ar_constr_args['data'], + 'name' : ar_constr_args['name'], + } + return args + + + diff --git a/test/test_strain.py b/test/test_strain.py new file mode 100644 index 000000000..c62e51cf3 --- /dev/null +++ b/test/test_strain.py @@ -0,0 +1,70 @@ +import py4DSTEM +from py4DSTEM import StrainMap +from os.path import join +from numpy import zeros + + +# TODO add BVs file to test suite with calibration, remove disk detection here + +# set filepath +path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") + + + +class TestStrainMap: + + # setup/teardown + def setup_class(cls): + + # Read sim Au datacube + datacube = py4DSTEM.io.read( + path, + data_id = 'polyAu_4DSTEM' + ) + + # prepare a probe + mask = zeros(datacube.Rshape,dtype=bool) + mask[28:33,14:19] = 1 + probe = datacube.get_vacuum_probe( ROI=mask ) + alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.calibration.get_probe_size( probe.probe ) + probe.get_kernel( + mode='sigmoid', + origin=(qx0_pr,qy0_pr), + radii=(alpha_pr,2*alpha_pr) + ) + + # Set disk detection parameters + detect_params = { + 'corrPower': 1.0, + 'sigma': 0, + 'edgeBoundary': 2, + 'minRelativeIntensity': 0, + 'minAbsoluteIntensity': 8, + 'minPeakSpacing': 4, + 'subpixel' : 'poly', + 'maxNumPeaks': 1000, + # 'CUDA': True, + } + + # find bragg peaks + cls.braggpeaks = datacube.find_Bragg_disks( + template = probe.kernel, + **detect_params, + ) + + # set an arbitrary origin + cls.braggpeaks.calibration.set_origin((0,0)) + + + + # tests + + def test_strainmap_instantiation(self): + + strainmap = StrainMap( + braggvectors = self.braggpeaks, + ) + + assert(isinstance(strainmap, StrainMap)) + + From 2d5cc7547b4e0b6a40f06d634bce98ba6d1a3046 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 15:55:20 -0700 Subject: [PATCH 168/362] bugfixes for probe constraints --- .../iterative_ptychographic_constraints.py | 3 +- py4DSTEM/process/phase/utils.py | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index d3c5b34a9..5fe1a1a35 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -412,6 +412,7 @@ def _probe_fourier_amplitude_constraint( updated_probe_fft, _, _, _ = regularize_probe_amplitude( asnumpy(current_probe_fft), width_max_pixels=width_max_pixels, + nearest_angular_neighbor_averaging=5, enforce_constant_intensity=enforce_constant_intensity, corner_centered=True, ) @@ -485,7 +486,7 @@ def _probe_aberration_fitting_constraint( fourier_probe_abs = xp.abs(fourier_probe) sampling = self.sampling - fitted_angle = fit_aberration_surface( + fitted_angle, _ = fit_aberration_surface( fourier_probe, sampling, max_angular_order, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 7f5287b3b..2d36284ee 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -12,10 +12,11 @@ cp = None from scipy.fft import dstn, idstn + from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from py4DSTEM.process.utils import get_CoM -from scipy.ndimage import gaussian_filter +from scipy.ndimage import gaussian_filter, uniform_filter1d from skimage.restoration import unwrap_phase # fmt: off @@ -1282,7 +1283,7 @@ def nesterov_gamma(zero_indexed_iter_num): def cartesian_to_polar_transform_2Ddata( im_cart, xy_center, - num_theta_bins=180, + num_theta_bins=90, radius_max=None, corner_centered=False, xp=np, @@ -1411,6 +1412,7 @@ def polar_to_cartesian_transform_2Ddata( def regularize_probe_amplitude( probe_init, width_max_pixels=2.0, + nearest_angular_neighbor_averaging=5, enforce_constant_intensity=True, corner_centered=False, ): @@ -1423,6 +1425,8 @@ def regularize_probe_amplitude( 2D complex image of the probe in Fourier space. width_max_pixels: float Maximum edge width of the probe in pixels. + nearest_angular_neighbor_averaging: int + Number of nearest angular neighbor pixels to average to make aperture less jagged. enforce_constant_intensity: bool Set to true to make intensity inside the aperture constant. corner_centered: bool @@ -1504,6 +1508,17 @@ def step_model(radius, sig_0, rad_0, width): xtol=1e-12, bounds=(lb, ub), )[0] + # polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) + + # make aperture less jagged, using moving mean + coefs_all = np.apply_along_axis( + uniform_filter1d, + 0, + coefs_all, + size=nearest_angular_neighbor_averaging, + mode="wrap", + ) + for a0 in range(polar_int.shape[0]): polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) # Convert back to cartesian coordinates @@ -1564,7 +1579,6 @@ def fit_aberration_surface( probe_sampling, max_angular_order, max_radial_order, - seed=1, xp=np, ): """ """ @@ -1572,11 +1586,12 @@ def fit_aberration_surface( probe_angle = xp.angle(complex_probe) if xp is np: - unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True, seed=seed) + probe_angle = probe_angle.astype(np.float64) + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True).astype(xp.float32) else: - unwrapped_angle = xp.asarray( - unwrap_phase(xp.asnumpy(probe_angle), wrap_around=True, seed=seed) - ) + probe_angle = xp.asnumpy(probe_angle).astype(np.float64) + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True) + unwrapped_angle = xp.asarray(unwrapped_angle).astype(xp.float32) basis, _ = aberrations_basis_function( complex_probe.shape, @@ -1595,4 +1610,4 @@ def fit_aberration_surface( fitted_angle = xp.tensordot(coeff, basis, axes=1) - return fitted_angle + return fitted_angle, coeff From 4403ce85dec3179698e477d0ff5902abc4c22c1f Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 19:21:34 -0400 Subject: [PATCH 169/362] new test --- test/test_misc.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/test_misc.py diff --git a/test/test_misc.py b/test/test_misc.py new file mode 100644 index 000000000..bac4d65ae --- /dev/null +++ b/test/test_misc.py @@ -0,0 +1,19 @@ +import py4DSTEM +import numpy as np + + +def test_attach(): + + x = py4DSTEM.DiffractionSlice(np.ones((5,5)), name='x') + y = py4DSTEM.DiffractionSlice(np.ones((5,5)), name='y') + + + x.calibration.set_Q_pixel_size(50) + y.calibration.set_Q_pixel_size(2) + + x.attach(y) + + assert('y' in x.treekeys) + assert(x.calibration.get_Q_pixel_size() == 50) + + From e83334de30feb8aaedc4e26906fb0cce6abd2ac9 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:27:57 -0700 Subject: [PATCH 170/362] probe constraints for mixed-state --- .../iterative_mixedstate_ptychography.py | 95 +++++++++---------- .../iterative_singleslice_ptychography.py | 12 +-- 2 files changed, 51 insertions(+), 56 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 69b2d8c45..56fec1004 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1106,15 +1106,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1145,14 +1145,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed - symmetrize_probe: bool - If True, the probe is radially-averaged + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1160,10 +1158,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray @@ -1232,16 +1231,14 @@ def _constraints( current_probe = self._probe_center_of_mass_constraint(current_probe) # These constraints don't _really_ make sense for mixed-state - if probe_gaussian_filter: - raise NotImplementedError() - if symmetrize_probe: - raise NotImplementedError() if fix_probe_aperture: raise NotImplementedError() - elif constrain_probe_amplitude: - raise NotImplementedError() elif constrain_probe_fourier_amplitude: raise NotImplementedError() + if fit_probe_aberrations: + raise NotImplementedError() + if constrain_probe_amplitude: + raise NotImplementedError() if orthogonalize_probe: current_probe = self._probe_orthogonalization_constraint(current_probe) @@ -1276,19 +1273,19 @@ def reconstruct( orthogonalize_probe: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1342,19 +1339,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate global_affine_transformation: bool, optional @@ -1363,12 +1359,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -1685,12 +1681,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -1698,7 +1688,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 2d5744e28..b561892cb 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1270,12 +1270,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float From 9fe98ccd5c0fcc64a0f6c12fae884ddaa2b32d29 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 19:29:59 -0400 Subject: [PATCH 171/362] get_probe_size fixes --- py4DSTEM/datacube/datacube.py | 13 ++++++------- py4DSTEM/process/calibration/probe.py | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index 96ec950ba..3031b3ff9 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -657,7 +657,7 @@ def get_probe_size( thresh_lower=0.01, thresh_upper=0.99, N=100, - plot = True, + plot = False, returncal = True, write_to_cal = True, **kwargs, @@ -707,13 +707,13 @@ def get_probe_size( from py4DSTEM.process.calibration import get_probe_size if dp is None: - assert 'dp_mean' in self._branch.keys(), "calculate .get_dp_mean()" + assert('dp_mean' in self.treekeys), "calculate .get_dp_mean() or pass a `dp` arg" DP = self.tree( 'dp_mean' ).data elif type(dp) == str: - assert dp in self._branch.keys(), "mode not found" - DP = self.attach( dp ) + assert(dp in self.treekeys), f"mode {dp} not found in the tree" + DP = self.tree( dp ) elif type(dp) == np.ndarray: - assert len(dp.shape) == 2, "must be a 2D array" + assert(dp.shape == self.Qshape), "must be a diffraction space shape 2D array" DP = dp x = get_probe_size( @@ -728,8 +728,7 @@ def get_probe_size( try: self.calibration.set_probe_param(x) except AttributeError: - # should we raise an error here? - pass + raise Exception('writing to calibrations were requested, but could not be completed') #plot results if plot: diff --git a/py4DSTEM/process/calibration/probe.py b/py4DSTEM/process/calibration/probe.py index c239590c5..f42a353b6 100644 --- a/py4DSTEM/process/calibration/probe.py +++ b/py4DSTEM/process/calibration/probe.py @@ -45,7 +45,6 @@ def get_probe_size(DP, thresh_lower=0.01, thresh_upper=0.99, N=100): # Get r for each mask DPmax = np.max(DP) - print(DPmax) for i in range(len(thresh_vals)): thresh = thresh_vals[i] mask = DP > DPmax * thresh From 2803c08f71e5b4f8c201a2295381efb985d4cff6 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 11 Jul 2023 16:35:19 -0700 Subject: [PATCH 172/362] remove print statement --- py4DSTEM/process/calibration/probe.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/calibration/probe.py b/py4DSTEM/process/calibration/probe.py index c239590c5..f42a353b6 100644 --- a/py4DSTEM/process/calibration/probe.py +++ b/py4DSTEM/process/calibration/probe.py @@ -45,7 +45,6 @@ def get_probe_size(DP, thresh_lower=0.01, thresh_upper=0.99, N=100): # Get r for each mask DPmax = np.max(DP) - print(DPmax) for i in range(len(thresh_vals)): thresh = thresh_vals[i] mask = DP > DPmax * thresh From 9ed2e36f0a9e11e160db3d031a7ef9a63fbacad7 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:37:46 -0700 Subject: [PATCH 173/362] probe constraints for multislice --- .../iterative_multislice_ptychography.py | 117 +++++++++--------- 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 4706decf9..1e9bd2cbb 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1455,15 +1455,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1498,14 +1498,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1513,10 +1511,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool If True, probe Fourier amplitude is replaced by initial_probe_aperture initial_probe_aperture: np.ndarray @@ -1612,31 +1611,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1668,20 +1665,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1740,19 +1737,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate global_affine_transformation: bool, optional @@ -1761,12 +1757,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2098,12 +2094,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2111,7 +2101,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, From ee78659e999f37c8c9791d90b96a96c98c1cfd42 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:51:30 -0700 Subject: [PATCH 174/362] probe constraints for overlap tomography --- .../iterative_overlap_magnetic_tomography.py | 130 +++++++++--------- .../phase/iterative_overlap_tomography.py | 130 +++++++++--------- 2 files changed, 124 insertions(+), 136 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 099d26bcb..4c7387763 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1685,15 +1685,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1725,14 +1725,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1740,10 +1738,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1836,31 +1835,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1892,21 +1889,21 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma_e: float = None, gaussian_filter_sigma_m: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass_e: float = None, q_lowpass_m: float = None, @@ -1960,19 +1957,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1986,12 +1982,12 @@ def reconstruct( Standard deviation of gaussian kernel for magnetic object in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2447,12 +2443,6 @@ def reconstruct( self._probe, self._positions_px_all[start_tilt:end_tilt], fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2460,7 +2450,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, @@ -2497,12 +2492,6 @@ def reconstruct( self._probe, None, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2510,7 +2499,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index b5a3f71fa..0293fd322 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1533,15 +1533,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1569,14 +1569,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1584,10 +1582,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1649,31 +1648,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1705,20 +1702,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1770,19 +1767,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1794,12 +1790,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2176,12 +2172,6 @@ def reconstruct( self._probe, self._positions_px_all[start_tilt:end_tilt], fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2189,7 +2179,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, @@ -2221,12 +2216,6 @@ def reconstruct( self._probe, None, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2234,7 +2223,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, From 03a25f1de3624d09921abe1c48ada04da7317814 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:56:03 -0700 Subject: [PATCH 175/362] probe constraints for simultaneous --- .../iterative_simultaneous_ptychography.py | 111 +++++++++--------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index cf243192e..8881d021c 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2210,15 +2210,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -2252,8 +2252,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -2261,10 +2265,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -2364,31 +2369,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -2422,21 +2425,21 @@ def reconstruct( fix_probe_iter: int = 0, warmup_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma_e: float = None, gaussian_filter_sigma_m: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass_e: float = None, q_lowpass_m: float = None, @@ -2492,19 +2495,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float @@ -2518,12 +2520,12 @@ def reconstruct( Standard deviation of gaussian kernel for magnetic object in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass_e: float @@ -2868,12 +2870,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2881,7 +2877,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, From 66d3794133d59e5dfe2b45142205d3b1592c6ecc Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 17:04:43 -0700 Subject: [PATCH 176/362] imports, formatting, linting --- py4DSTEM/process/phase/.gitignore | 1 + py4DSTEM/process/phase/__init__.py | 29 ++++++++++++++----- py4DSTEM/process/phase/iterative_dpc.py | 2 +- .../iterative_overlap_magnetic_tomography.py | 6 +++- .../phase/iterative_overlap_tomography.py | 6 +++- .../iterative_ptychographic_constraints.py | 2 +- py4DSTEM/process/phase/utils.py | 5 ++-- 7 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 py4DSTEM/process/phase/.gitignore diff --git a/py4DSTEM/process/phase/.gitignore b/py4DSTEM/process/phase/.gitignore new file mode 100644 index 000000000..c97f963b3 --- /dev/null +++ b/py4DSTEM/process/phase/.gitignore @@ -0,0 +1 @@ +*.sh diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index cb9176375..178079349 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -3,13 +3,28 @@ _emd_hook = True from py4DSTEM.process.phase.iterative_dpc import DPCReconstruction -from py4DSTEM.process.phase.iterative_mixedstate_ptychography import MixedstatePtychographicReconstruction -from py4DSTEM.process.phase.iterative_multislice_ptychography import MultislicePtychographicReconstruction -from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import OverlapMagneticTomographicReconstruction -from py4DSTEM.process.phase.iterative_overlap_tomography import OverlapTomographicReconstruction +from py4DSTEM.process.phase.iterative_mixedstate_ptychography import ( + MixedstatePtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_multislice_ptychography import ( + MultislicePtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import ( + OverlapMagneticTomographicReconstruction, +) +from py4DSTEM.process.phase.iterative_overlap_tomography import ( + OverlapTomographicReconstruction, +) from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction -from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction -from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction -from py4DSTEM.process.phase.parameter_optimize import OptimizationParameter, PtychographyOptimizer +from py4DSTEM.process.phase.iterative_simultaneous_ptychography import ( + SimultaneousPtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_singleslice_ptychography import ( + SingleslicePtychographicReconstruction, +) +from py4DSTEM.process.phase.parameter_optimize import ( + OptimizationParameter, + PtychographyOptimizer, +) # fmt: on diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index dc0df2ce6..d9dfd1514 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -4,7 +4,7 @@ """ import warnings -from typing import Tuple, Union, Sequence +from typing import Sequence, Tuple, Union import matplotlib.pyplot as plt import numpy as np diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 4c7387763..8691a121d 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -2487,7 +2487,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 0293fd322..d6bee12fd 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2211,7 +2211,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 5fe1a1a35..c5aef16c6 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -3,8 +3,8 @@ array_slice, estimate_global_transformation_ransac, fft_shift, - regularize_probe_amplitude, fit_aberration_surface, + regularize_probe_amplitude, ) from py4DSTEM.process.utils import get_CoM diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 2d36284ee..c2e1d3b77 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1,8 +1,8 @@ +import functools from typing import Mapping, Tuple, Union import matplotlib.pyplot as plt import numpy as np -import functools from scipy.optimize import curve_fit try: @@ -12,10 +12,9 @@ cp = None from scipy.fft import dstn, idstn - +from py4DSTEM.process.utils import get_CoM from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom -from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter, uniform_filter1d from skimage.restoration import unwrap_phase From b41cea746570403022c0cadf4a708fd33ab0fee2 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 21:03:44 -0400 Subject: [PATCH 177/362] datacube.copy bugfix --- py4DSTEM/data/data.py | 2 +- test/test_misc.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/test_misc.py diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index ba82f4fec..85b3653f2 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -73,12 +73,12 @@ def __init__( self.calibration = Calibration() else: assert(isinstance(calibration,Calibration)), f"`calibration` must be a Calibration, not type {type(calibration)}" - self.calibration = calibration if calibration.root is None: calibration._root = Root( name = self.name+"_root" ) calibration.root.tree( self ) else: calibration.root.tree( self ) + self.calibration = calibration # calibration property diff --git a/test/test_misc.py b/test/test_misc.py new file mode 100644 index 000000000..275eb767b --- /dev/null +++ b/test/test_misc.py @@ -0,0 +1,32 @@ +import py4DSTEM +import numpy as np + + +def test_attach(): + """ tests to make sure Data.attach handles metadata merging correctly + """ + + x = py4DSTEM.DiffractionSlice(np.ones((5,5)), name='x') + y = py4DSTEM.DiffractionSlice(np.ones((5,5)), name='y') + + + x.calibration.set_Q_pixel_size(50) + y.calibration.set_Q_pixel_size(2) + + x.attach(y) + + assert('y' in x.treekeys) + assert(x.calibration.get_Q_pixel_size() == 50) + + +def test_datacube_copy(): + """ tests datacube.copy() + """ + x = py4DSTEM.DataCube(data=np.zeros((3,3,4,4))) + y = x.copy() + assert(isinstance(y,py4DSTEM.DataCube)) + + + + + From 21ec315e7d5d85893f41e554b6da7ae8e630ab1a Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 21:38:47 -0400 Subject: [PATCH 178/362] edits --- py4DSTEM/braggvectors/braggvector_methods.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index e04a7558a..8446807cc 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -541,7 +541,7 @@ def fit_origin( try: self.calibration.set_origin([qx0_fit,qy0_fit]) except AttributeError: - # should a warning be raised? + warn("No calibration found on this datacube - fit values are not being stored") pass if plot: from py4DSTEM.visualize import show_image_grid @@ -573,6 +573,10 @@ def fit_origin( W = 3, cmap = cmap, axsize = axsize, + title = [ + 'measured origin, x', 'fitorigin, x', 'residuals, x', + 'measured origin, y', 'fitorigin, y', 'residuals, y' + ], vmin = -1*plot_range, vmax = 1*plot_range, intensity_range = "absolute", From 138673480af5481db589ab67869136808b1879d8 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 22:11:15 -0400 Subject: [PATCH 179/362] edits --- py4DSTEM/visualize/vis_grid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/visualize/vis_grid.py b/py4DSTEM/visualize/vis_grid.py index 8ca9c477d..48b5b158a 100644 --- a/py4DSTEM/visualize/vis_grid.py +++ b/py4DSTEM/visualize/vis_grid.py @@ -97,7 +97,7 @@ def show_image_grid( H,W, axsize=(6,6), returnfig=False, - figax = None, + figax = None, title = None, title_index = False, suptitle = None, From 2721ed7f51d2c95437479c6db25fbd0f5d500a7e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 22:18:50 -0400 Subject: [PATCH 180/362] adds strain test file --- py4DSTEM/io/google_drive_downloader.py | 7 ++++ test/gettestdata.py | 5 ++- test/test_strain.py | 44 +++----------------------- 3 files changed, 15 insertions(+), 41 deletions(-) diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index c8b410d47..51e3a70d7 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -83,6 +83,10 @@ 'test_realslice_io.h5', '1siH80-eRJwG5R6AnU4vkoqGWByrrEz1y' ), + 'test_strain' : ( + 'downsample_Si_SiGe_analysis_braggdisks_cal.h5', + '1bYgDdAlnWHyFmY-SwN3KVpMutWBI5MhP' + ) } # collections of files @@ -110,6 +114,9 @@ ), 'test_braggvectors' : ( 'Au_sim', + ), + 'strain' : ( + 'test_strain', ) } diff --git a/test/gettestdata.py b/test/gettestdata.py index 0b5608a7c..b3d8a0a40 100644 --- a/test/gettestdata.py +++ b/test/gettestdata.py @@ -19,7 +19,8 @@ data_options = [ 'tutorials', 'io', - 'basic' + 'basic', + 'strain', ] # Add arguments @@ -57,6 +58,8 @@ data = 'test_io' elif args.data == 'basic': data = 'small_datacube' +elif args.data == 'strain': + data = 'strain' else: raise Exception(f"invalid data choice, {parser.data}") diff --git a/test/test_strain.py b/test/test_strain.py index c62e51cf3..1e34c5b6c 100644 --- a/test/test_strain.py +++ b/test/test_strain.py @@ -7,7 +7,7 @@ # TODO add BVs file to test suite with calibration, remove disk detection here # set filepath -path = join(py4DSTEM._TESTPATH,"test_io/legacy_v0.9_simAuNanoplatelet_bin.h5") +path = join(py4DSTEM._TESTPATH,"strain/downsample_Si_SiGe_analysis_braggdisks_cal.h5") @@ -16,45 +16,9 @@ class TestStrainMap: # setup/teardown def setup_class(cls): - # Read sim Au datacube - datacube = py4DSTEM.io.read( - path, - data_id = 'polyAu_4DSTEM' - ) - - # prepare a probe - mask = zeros(datacube.Rshape,dtype=bool) - mask[28:33,14:19] = 1 - probe = datacube.get_vacuum_probe( ROI=mask ) - alpha_pr,qx0_pr,qy0_pr = py4DSTEM.process.calibration.get_probe_size( probe.probe ) - probe.get_kernel( - mode='sigmoid', - origin=(qx0_pr,qy0_pr), - radii=(alpha_pr,2*alpha_pr) - ) - - # Set disk detection parameters - detect_params = { - 'corrPower': 1.0, - 'sigma': 0, - 'edgeBoundary': 2, - 'minRelativeIntensity': 0, - 'minAbsoluteIntensity': 8, - 'minPeakSpacing': 4, - 'subpixel' : 'poly', - 'maxNumPeaks': 1000, - # 'CUDA': True, - } - - # find bragg peaks - cls.braggpeaks = datacube.find_Bragg_disks( - template = probe.kernel, - **detect_params, - ) - - # set an arbitrary origin - cls.braggpeaks.calibration.set_origin((0,0)) - + # Read braggpeaks + # origin is calibrated + cls.braggpeaks = py4DSTEM.io.read( path ) # tests From e71c1bc24bfa15623b4e47c7bfcc9923473edcd5 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 22:27:11 -0400 Subject: [PATCH 181/362] hotfix, legacy 13 reader rootnode bug --- py4DSTEM/io/legacy/legacy13/v13_to_14.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/legacy/legacy13/v13_to_14.py b/py4DSTEM/io/legacy/legacy13/v13_to_14.py index a9d188b03..18c08c777 100644 --- a/py4DSTEM/io/legacy/legacy13/v13_to_14.py +++ b/py4DSTEM/io/legacy/legacy13/v13_to_14.py @@ -93,7 +93,7 @@ def _populate_tree(node13,node14,root14): if isinstance(newnode14,Metadata): pass else: - node14.tree(newnode14) + node14.tree(newnode14,force=True) _populate_tree(newnode13,newnode14,root14) From af7e87b17a6b609f4ff3d6e791e08c784b1a4152 Mon Sep 17 00:00:00 2001 From: cophus Date: Tue, 11 Jul 2023 19:51:46 -0700 Subject: [PATCH 182/362] Updating beamstop mask function, fixing bug --- py4DSTEM/datacube/datacube.py | 53 +++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index 96ec950ba..aee760496 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -1016,8 +1016,11 @@ def find_Bragg_disks( def get_beamstop_mask( self, threshold = 0.25, - distance_edge = 4.0, + distance_edge = 2.0, include_edges = True, + sigma = 0, + use_max_dp = False, + scale_radial = None, name = "mask_beamstop", returncalc = True, ): @@ -1032,6 +1035,12 @@ def get_beamstop_mask( distance_edge (float): How many pixels to expand the mask. include_edges (bool): If set to True, edge pixels will be included in the mask. + sigma (float): + Gaussain blur std to apply to image before thresholding. + use_max_dp (bool): + Use the max DP instead of the mean DP. + scale_radial (float): + Scale from center of image by this factor (can help with edge) name (string): Name of the output array. returncalc (bool): Set to true to return the result. @@ -1040,19 +1049,41 @@ def get_beamstop_mask( """ - # Calculate dp_mean if needed - if not "dp_mean" in self._branch.keys(): - self.get_dp_mean(); - - # normalized dp_mean - int_sort = np.sort(self.tree("dp_mean").data.ravel()) + if scale_radial is not None: + x = np.arange(self.data.shape[2]) * 2.0 / self.data.shape[2] + y = np.arange(self.data.shape[3]) * 2.0 / self.data.shape[3] + ya, xa = np.meshgrid(y - np.mean(y), x - np.mean(x)) + im_scale = 1.0 + np.sqrt(xa**2 + ya**2)*scale_radial + + # Get image for beamstop mask + if use_max_dp: + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_max(); + # im = self.tree["dp_max"].data.astype('float') + if not "dp_max" in self._branch.keys(): + self.get_dp_max(); + im = self.tree("dp_max").data.astype('float') + else: + if not "dp_mean" in self._branch.keys(): + self.get_dp_mean(); + im = self.tree("dp_mean").data + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_mean(); + # im = self.tree["dp_mean"].data.astype('float') + + # smooth and scale if needed + if sigma > 0.0: + im = gaussian_filter(im, sigma, mode='nearest') + if scale_radial is not None: + im *= im_scale + + # Calculate beamstop mask + int_sort = np.sort(im.ravel()) ind = np.round(np.clip( int_sort.shape[0]*threshold, 0,int_sort.shape[0])).astype('int') intensity_threshold = int_sort[ind] - - # Use threshold to calculate initial mask - mask_beamstop = self.tree("dp_mean").data >= intensity_threshold + mask_beamstop = im >= intensity_threshold # clean up mask mask_beamstop = np.logical_not(binary_fill_holes(np.logical_not(mask_beamstop))) @@ -1089,7 +1120,7 @@ def get_beamstop_mask( ) # Add to tree - self.attach( mask_beamstop ) + self.tree(x) # return if returncalc: From db78022cd0d837e33f4088b964e5b7567921e315 Mon Sep 17 00:00:00 2001 From: cophus Date: Tue, 11 Jul 2023 20:05:35 -0700 Subject: [PATCH 183/362] Removing errant print statement in get_probe_size() --- py4DSTEM/braggvectors/probe.py | 1 + py4DSTEM/process/calibration/probe.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/braggvectors/probe.py b/py4DSTEM/braggvectors/probe.py index 32adfe1f2..da6d32b47 100644 --- a/py4DSTEM/braggvectors/probe.py +++ b/py4DSTEM/braggvectors/probe.py @@ -550,6 +550,7 @@ def get_probe_kernel_edge_sigmoid( np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) qr = np.sqrt(qx**2 + qy**2) + # Calculate sigmoid if type == 'logistic': r0 = 0.5*(ro+ri) diff --git a/py4DSTEM/process/calibration/probe.py b/py4DSTEM/process/calibration/probe.py index c239590c5..f42a353b6 100644 --- a/py4DSTEM/process/calibration/probe.py +++ b/py4DSTEM/process/calibration/probe.py @@ -45,7 +45,6 @@ def get_probe_size(DP, thresh_lower=0.01, thresh_upper=0.99, N=100): # Get r for each mask DPmax = np.max(DP) - print(DPmax) for i in range(len(thresh_vals)): thresh = thresh_vals[i] mask = DP > DPmax * thresh From 884dcd3f9986ab1df1870890744633459ed0b064 Mon Sep 17 00:00:00 2001 From: cophus Date: Tue, 11 Jul 2023 20:23:56 -0700 Subject: [PATCH 184/362] Fix for in-place modification of dp_mean() --- py4DSTEM/datacube/datacube.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index aee760496..524b796b9 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -1062,11 +1062,11 @@ def get_beamstop_mask( # im = self.tree["dp_max"].data.astype('float') if not "dp_max" in self._branch.keys(): self.get_dp_max(); - im = self.tree("dp_max").data.astype('float') + im = self.tree("dp_max").data.copy().astype('float') else: if not "dp_mean" in self._branch.keys(): self.get_dp_mean(); - im = self.tree("dp_mean").data + im = self.tree("dp_mean").data.copy() # if not "dp_mean" in self.tree.keys(): # self.get_dp_mean(); # im = self.tree["dp_mean"].data.astype('float') From e446b04b3b5a790213ae887579b4b934a56760ab Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 12 Jul 2023 00:16:56 -0400 Subject: [PATCH 185/362] updates --- py4DSTEM/braggvectors/braggvector_methods.py | 80 ------------ py4DSTEM/data/data.py | 9 +- py4DSTEM/process/strain.py | 128 +++++++++++++++++-- test/test_strain.py | 3 - 4 files changed, 122 insertions(+), 98 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 8446807cc..53f800ed1 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -637,86 +637,6 @@ def fit_p_ellipse( # Deprecated?? - # Lattice vectors - def choose_lattice_vectors( - self, - index_g0, - index_g1, - index_g2, - mode = 'centered', - plot = True, - subpixel = 'multicorr', - upsample_factor = 16, - sigma=0, - minAbsoluteIntensity=0, - minRelativeIntensity=0, - relativeToPeak=0, - minSpacing=0, - edgeBoundary=1, - maxNumPeaks=10, - bvm_vis_params = {}, - returncalc = False, - ): - """ - Choose which lattice vectors to use for strain mapping. - - Args: - index_g0 (int): origin - index_g1 (int): second point of vector 1 - index_g2 (int): second point of vector 2 - mode (str): centered or raw bragg map - plot (bool): plot bragg vector maps and vectors - subpixel (str): specifies the subpixel resolution algorithm to use. - must be in ('pixel','poly','multicorr'), which correspond - to pixel resolution, subpixel resolution by fitting a - parabola, and subpixel resultion by Fourier upsampling. - upsample_factor: the upsampling factor for the 'multicorr' - algorithm - sigma: if >0, applies a gaussian filter - maxNumPeaks: the maximum number of maxima to return - minAbsoluteIntensity, minRelativeIntensity, relativeToPeak, - minSpacing, edgeBoundary, maxNumPeaks: filtering applied - after maximum detection and before subpixel refinement - """ - from py4DSTEM.process.utils import get_maxima_2D - - if mode == "centered": - bvm = self.bvm_centered - else: - bvm = self.bvm_raw - - g = get_maxima_2D( - bvm, - subpixel = subpixel, - upsample_factor = upsample_factor, - sigma = sigma, - minAbsoluteIntensity = minAbsoluteIntensity, - minRelativeIntensity = minRelativeIntensity, - relativeToPeak = relativeToPeak, - minSpacing = minSpacing, - edgeBoundary = edgeBoundary, - maxNumPeaks = maxNumPeaks, - ) - - self.g = g - - from py4DSTEM.visualize import select_lattice_vectors - g1,g2 = select_lattice_vectors( - bvm, - gx = g['x'], - gy = g['y'], - i0 = index_g0, - i1 = index_g1, - i2 = index_g2, - **bvm_vis_params, - ) - - self.g1 = g1 - self.g2 = g2 - - if returncalc: - return g1, g2 - def index_bragg_directions( self, x0 = None, diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index ba82f4fec..1a6c5adaf 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -68,9 +68,12 @@ def __init__( # set up calibration + EMD tree if calibration is None: - root = Root( name = self.name+"_root" ) - root.tree( self ) - self.calibration = Calibration() + if self.root is not None and 'calibration' in self.root.metadata: + pass + else: + root = Root( name = self.name+"_root" ) + root.tree( self ) + self.calibration = Calibration() else: assert(isinstance(calibration,Calibration)), f"`calibration` must be a Calibration, not type {type(calibration)}" self.calibration = calibration diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 159bc3265..e999c02d1 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -23,23 +23,17 @@ def __init__( """ TODO """ - # set up braggvectors - self.braggvectors = braggvectors - # TODO - how to handle changes to braggvectors - # TODO - ellipse cal or no? - - # set up data - data = np.empty(( - self.braggvectors.Rshape[0], - self.braggvectors.Rshape[1], - 6 - )) + assert(isinstance(braggvectors,BraggVectors)), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" # initialize as a RealSlice RealSlice.__init__( self, name = name, - data = data, + data = np.empty(( + 6, + braggvectors.Rshape[0], + braggvectors.Rshape[1], + )), slicelabels = [ 'exx', 'eyy', @@ -50,6 +44,21 @@ def __init__( ] ) + # set up braggvectors + self.braggvectors = braggvectors + # TODO - how to handle changes to braggvectors + # option: register with calibrations and add a .calibrate method + # which {{does something}} when origin changes + # TODO - include ellipse cal or no? + + assert(self.root is not None) + + # initialize as Data + Data.__init__( + self, + calibration = self.braggvectors.calibration + ) + # braggvector properties @@ -61,7 +70,102 @@ def braggvectors(self,x): assert(isinstance(x,BraggVectors)), f".braggvectors must be BraggVectors, not type {type(x)}" assert(x.calibration.origin is not None), f"braggvectors must have a calibrated origin" self._braggvectors = x + self._braggvectors.tree(self,force=True) + + + + # Class methods + + def choose_lattice_vectors( + self, + index_g0, + index_g1, + index_g2, + mode = 'centered', + plot = True, + subpixel = 'multicorr', + upsample_factor = 16, + sigma=0, + minAbsoluteIntensity=0, + minRelativeIntensity=0, + relativeToPeak=0, + minSpacing=0, + edgeBoundary=1, + maxNumPeaks=10, + bvm_vis_params = {}, + returncalc = False, + ): + """ + Choose which lattice vectors to use for strain mapping. + + Args: + index_g0 (int): origin + index_g1 (int): second point of vector 1 + index_g2 (int): second point of vector 2 + mode (str): centered or raw bragg map + plot (bool): plot bragg vector maps and vectors + subpixel (str): specifies the subpixel resolution algorithm to use. + must be in ('pixel','poly','multicorr'), which correspond + to pixel resolution, subpixel resolution by fitting a + parabola, and subpixel resultion by Fourier upsampling. + upsample_factor: the upsampling factor for the 'multicorr' + algorithm + sigma: if >0, applies a gaussian filter + maxNumPeaks: the maximum number of maxima to return + minAbsoluteIntensity, minRelativeIntensity, relativeToPeak, + minSpacing, edgeBoundary, maxNumPeaks: filtering applied + after maximum detection and before subpixel refinement + """ + from py4DSTEM.process.utils import get_maxima_2D + + if mode == "centered": + bvm = self.bvm_centered + else: + bvm = self.bvm_raw + + g = get_maxima_2D( + bvm, + subpixel = subpixel, + upsample_factor = upsample_factor, + sigma = sigma, + minAbsoluteIntensity = minAbsoluteIntensity, + minRelativeIntensity = minRelativeIntensity, + relativeToPeak = relativeToPeak, + minSpacing = minSpacing, + edgeBoundary = edgeBoundary, + maxNumPeaks = maxNumPeaks, + ) + + self.g = g + + from py4DSTEM.visualize import select_lattice_vectors + g1,g2 = select_lattice_vectors( + bvm, + gx = g['x'], + gy = g['y'], + i0 = index_g0, + i1 = index_g1, + i2 = index_g2, + **bvm_vis_params, + ) + + self.g1 = g1 + self.g2 = g2 + + if returncalc: + return g1, g2 + + + + + + + + + + + # IO methods # TODO - copy method diff --git a/test/test_strain.py b/test/test_strain.py index 1e34c5b6c..5bfa0efd3 100644 --- a/test/test_strain.py +++ b/test/test_strain.py @@ -4,13 +4,10 @@ from numpy import zeros -# TODO add BVs file to test suite with calibration, remove disk detection here - # set filepath path = join(py4DSTEM._TESTPATH,"strain/downsample_Si_SiGe_analysis_braggdisks_cal.h5") - class TestStrainMap: # setup/teardown From ed4ec1724dadf3c8e82144169a4256a62c569b3b Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Wed, 12 Jul 2023 09:02:37 -0700 Subject: [PATCH 186/362] fix for binning --- py4DSTEM/preprocess/preprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 8d95ccd81..1996dca1e 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -282,7 +282,7 @@ def bin_data_diffraction( datacube.calibration.set_Q_pixel_size(Qpixsize) # remake Cartesian coordinate system - datacube.qyy,datacube.qxx = np.meshgrid( + datacube._qyy,datacube._qxx = np.meshgrid( np.arange(0,datacube.Q_Ny), np.arange(0,datacube.Q_Nx) ) From df72ada80b28729d24e1c449dd59164306bf629a Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 12 Jul 2023 11:34:13 -0700 Subject: [PATCH 187/362] commenting out probe renormalizations post-constraints --- .../iterative_ptychographic_constraints.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index c5aef16c6..9af22ba92 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -364,7 +364,7 @@ def _probe_amplitude_constraint( erf = self._erf probe_intensity = xp.abs(current_probe) ** 2 - current_probe_sum = xp.sum(probe_intensity) + #current_probe_sum = xp.sum(probe_intensity) X = xp.fft.fftfreq(current_probe.shape[0])[:, None] Y = xp.fft.fftfreq(current_probe.shape[1])[None] @@ -374,10 +374,10 @@ def _probe_amplitude_constraint( tophat_mask = 0.5 * (1 - erf(sigma * r / (1 - r**2))) updated_probe = current_probe * tophat_mask - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_fourier_amplitude_constraint( self, @@ -406,7 +406,7 @@ def _probe_fourier_amplitude_constraint( xp = self._xp asnumpy = self._asnumpy - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + #current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft = xp.fft.fft2(current_probe) updated_probe_fft, _, _, _ = regularize_probe_amplitude( @@ -419,10 +419,10 @@ def _probe_fourier_amplitude_constraint( updated_probe_fft = xp.asarray(updated_probe_fft) updated_probe = xp.fft.ifft2(updated_probe_fft) - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_aperture_constraint( self, @@ -444,16 +444,16 @@ def _probe_aperture_constraint( """ xp = self._xp - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + #current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft_phase = xp.angle(xp.fft.fft2(current_probe)) updated_probe = xp.fft.ifft2( xp.exp(1j * current_probe_fft_phase) * initial_probe_aperture ) - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_aberration_fitting_constraint( self, From 40b91df818c4131f7a33433a2eec5ccb83b87541 Mon Sep 17 00:00:00 2001 From: cophus Date: Wed, 12 Jul 2023 15:45:25 -0700 Subject: [PATCH 188/362] Various changes to ACOM and BraggVectors --- py4DSTEM/braggvectors/braggvector_methods.py | 57 +++++++++++---- py4DSTEM/braggvectors/braggvectors.py | 26 ++++++- py4DSTEM/process/diffraction/crystal.py | 15 ++-- .../process/diffraction/crystal_calibrate.py | 33 +++++---- py4DSTEM/process/diffraction/crystal_viz.py | 72 +++++++++++++------ 5 files changed, 148 insertions(+), 55 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index cf267b42d..e48834d7d 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -187,7 +187,11 @@ def get_virtual_image( mode = None, geometry = None, name = 'bragg_virtual_image', - returncalc = True + returncalc = True, + center = True, + ellipse = True, + pixel = True, + rotate = True, ): ''' Calculates a virtual image based on the values of the Braggvectors @@ -205,13 +209,22 @@ def get_virtual_image( - 'circle', 'circular': nested 2-tuple, ((qx,qy),radius) - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)) - All values are in pixels. Note that (qx,qy) can be skipped, which - assumes peaks centered at (0,0) + Values can be in pixels or calibrated units. Note that (qx,qy) + can be skipped, which assumes peaks centered at (0,0). + center: bool + Apply calibration - center coordinate. + ellipse: bool + Apply calibration - elliptical correction. + pixel: bool + Apply calibration - pixel size. + rotate: bool + Apply calibration - QR rotation. Returns ------- virtual_im : VirtualImage ''' + # parse inputs circle_modes = ['circular','circle'] annulus_modes = ['annular','annulus'] @@ -221,13 +234,13 @@ def get_virtual_image( # set geometry if mode is None: if geometry is None: - center = None + qxy_center = None radial_range = np.array((0,np.inf)) else: if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) if isinstance(geometry[1], int) or isinstance(geometry[1], float): radial_range = np.array((0,geometry[1])) elif len(geometry[1]) == 0: @@ -237,30 +250,44 @@ def get_virtual_image( elif mode == 'circular' or mode == 'circle': radial_range = np.array((0,geometry[1])) if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) elif mode == 'annular' or mode == 'annulus': radial_range = np.array(geometry[1]) if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) # allocate space im_virtual = np.zeros(self.shape) # generate image - for rx,ry in tqdmnd(self.shape[0],self.shape[1]): - p = self.raw[rx,ry] + for rx,ry in tqdmnd( + self.shape[0], + self.shape[1], + ): + # Get user-specified Bragg vectors + p = self.get_vectors( + rx, + ry, + center = center, + ellipse = ellipse, + pixel = pixel, + rotate = rotate, + ) + if p.data.shape[0] > 0: if radial_range is None: im_virtual[rx,ry] = np.sum(p.I) else: - if center is None: + if qxy_center is None: qr = np.hypot(p.qx,p.qy) else: - qr = np.hypot(p.qx - center[0],p.qy - center[1]) + qr = np.hypot( + p.qx - qxy_center[0], + p.qy - qxy_center[1]) sub = np.logical_and( qr >= radial_range[0], qr < radial_range[1]) @@ -285,7 +312,7 @@ def get_virtual_image( } ) # attach to the tree - self.attach( ans) + self.attach(ans) # return if returncalc: diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index af1078981..d3f4a42c5 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -250,7 +250,7 @@ def get_vectors( ellipse, pixel, rotate - ): + ): """ Returns the bragg vectors at the specified scan position with the specified calibration state. @@ -268,6 +268,7 @@ def get_vectors( ------- vectors : BVects """ + ans = self._v_uncal[scan_x,scan_y].data ans = self.cal._transform( data = ans, @@ -280,15 +281,36 @@ def get_vectors( ) return BVects(ans) + def get_vectors_calibrated( + self, + scan_x, + scan_y, + ): + """ + Returns the calibrated bragg vectors at the specified scan position. + """ + ans = self._v_uncal[scan_x,scan_y].data + ans = self.cal._transform( + data = ans, + cal = self.calibration, + scanxy = (scan_x,scan_y), + center = True, + ellipse = True, + pixel = True, + rotate = True, + ) + return BVects(ans) + # copy - def copy(self, name=None): name = name if name is not None else self.name+"_copy" braggvector_copy = BraggVectors(self.Rshape, self.Qshape, name=name) braggvector_copy._v_uncal = self._v_uncal.copy() for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() + # TODO - fix this calibration line? + braggvector_copy.calibration = self.calibration return braggvector_copy diff --git a/py4DSTEM/process/diffraction/crystal.py b/py4DSTEM/process/diffraction/crystal.py index 228602692..3be87eb25 100644 --- a/py4DSTEM/process/diffraction/crystal.py +++ b/py4DSTEM/process/diffraction/crystal.py @@ -898,12 +898,19 @@ def calculate_bragg_peak_histogram( k = np.arange(k_min, k_max + k_step, k_step) k_num = k.shape[0] - # experimental data histogram + # concatenate all peaks bigpl = np.concatenate( [ - bragg_peaks.cal[i, j].data - for i in range(bragg_peaks.shape[0]) - for j in range(bragg_peaks.shape[1]) + bragg_peaks.get_vectors( + rx, + ry, + center = True, + ellipse = True, + pixel = True, + rotate = True, + ).data + for rx in range(bragg_peaks.shape[0]) + for ry in range(bragg_peaks.shape[1]) ] ) qr = np.sqrt(bigpl["qx"] ** 2 + bigpl["qy"] ** 2) diff --git a/py4DSTEM/process/diffraction/crystal_calibrate.py b/py4DSTEM/process/diffraction/crystal_calibrate.py index 2d08cd03c..d4be6abce 100644 --- a/py4DSTEM/process/diffraction/crystal_calibrate.py +++ b/py4DSTEM/process/diffraction/crystal_calibrate.py @@ -24,7 +24,7 @@ def calibrate_pixel_size( k_step = 0.002, k_broadening = 0.002, fit_all_intensities = True, - set_calibration = True, + set_calibration_in_place = False, verbose = True, plot_result = False, figsize: Union[list, tuple, np.ndarray] = (12, 6), @@ -60,8 +60,13 @@ def calibrate_pixel_size( figsize (list, tuple, np.ndarray): Figure size of the plot. returnfig (bool): Return handles figure and axis - Returns: - fig, ax (handles): Optional figure and axis handles, if returnfig=True. + Returns + _______ + + + + fig, ax: handles, optional + Figure and axis handles, if returnfig=True. """ @@ -112,17 +117,21 @@ def fit_profile(k, *coefs): # Get the answer pix_size_prev = bragg_peaks.calibration.get_Q_pixel_size() - ans = pix_size_prev / scale_pixel_size + pixel_size_new = pix_size_prev / scale_pixel_size - # if requested, apply calibrations - if set_calibration: - bragg_peaks.calibration.set_Q_pixel_size( ans ) + # if requested, apply calibrations in place + if set_calibration_in_place: + bragg_peaks.calibration.set_Q_pixel_size( pixel_size_new ) bragg_peaks.calibration.set_Q_pixel_units('A^-1') - bragg_peaks.setcal() - # Output + # Output calibrated Bragg peaks + bragg_peaks_cali = bragg_peaks.copy() + bragg_peaks_cali.calibration.set_Q_pixel_size( pixel_size_new ) + bragg_peaks_cali.calibration.set_Q_pixel_units('A^-1') + + # Output pixel size if verbose: - print(f"Calibrated pixel size = {np.round(ans, decimals=8)} A^-1") + print(f"Calibrated pixel size = {np.round(pixel_size_new, decimals=8)} A^-1") # Plotting if plot_result: @@ -163,9 +172,9 @@ def fit_profile(k, *coefs): # return if returnfig and plot_result: - return ans, (fig,ax) + return bragg_peaks_cali, (fig,ax) else: - return ans + return bragg_peaks_cali diff --git a/py4DSTEM/process/diffraction/crystal_viz.py b/py4DSTEM/process/diffraction/crystal_viz.py index 9c1f5b667..9395682a0 100644 --- a/py4DSTEM/process/diffraction/crystal_viz.py +++ b/py4DSTEM/process/diffraction/crystal_viz.py @@ -296,30 +296,48 @@ def plot_scattering_intensity( bragg_k_power=0.0, bragg_intensity_power=1.0, bragg_k_broadening=0.005, - figsize: Union[list, tuple, np.ndarray] = (12, 6), + figsize: Union[list, tuple, np.ndarray] = (10, 4), returnfig: bool = False, ): """ 1D plot of the structure factors - Args: - k_min (float): min k value for profile range. - k_max (float): max k value for profile range. - k_step (float): step size of k in profile range. - k_broadening (float): Broadening of simulated pattern. - k_power_scale (float): Scale SF intensities by k**k_power_scale. - int_power_scale (float): Scale SF intensities**int_power_scale. - int_scale (float): Scale output profile by this value. - remove_origin (bool): Remove origin from plot. - bragg_peaks (BraggVectors): Passed in bragg_peaks for comparison with simulated pattern. - bragg_k_power (float): bragg_peaks scaled by k**bragg_k_power. - bragg_intensity_power (float): bragg_peaks scaled by intensities**bragg_intensity_power. - bragg_k_broadening float): Broadening applied to bragg_peaks. - figsize (list, tuple, np.ndarray): Figure size for plot. - returnfig (bool): Return figure and axes handles if this is True. - - Returns: - fig, ax (optional) figure and axes handles + Parameters + -------- + + k_min: float + min k value for profile range. + k_max: float + max k value for profile range. + k_step: float + Step size of k in profile range. + k_broadening: float + Broadening of simulated pattern. + k_power_scale: float + Scale SF intensities by k**k_power_scale. + int_power_scale: float + Scale SF intensities**int_power_scale. + int_scale: float + Scale output profile by this value. + remove_origin: bool + Remove origin from plot. + bragg_peaks: BraggVectors + Passed in bragg_peaks for comparison with simulated pattern. + bragg_k_power: float + bragg_peaks scaled by k**bragg_k_power. + bragg_intensity_power: float + bragg_peaks scaled by intensities**bragg_intensity_power. + bragg_k_broadening: float + Broadening applied to bragg_peaks. + figsize: list, tuple, np.ndarray + Figure size for plot. + returnfig (bool): + Return figure and axes handles if this is True. + + Returns + -------- + fig, ax (optional) + figure and axes handles """ # k coordinates @@ -345,9 +363,16 @@ def plot_scattering_intensity( # concatenate all peaks bigpl = np.concatenate( [ - bragg_peaks.cal[i, j].data - for i in range(bragg_peaks.shape[0]) - for j in range(bragg_peaks.shape[1]) + bragg_peaks.get_vectors( + rx, + ry, + center = True, + ellipse = True, + pixel = True, + rotate = True, + ).data + for rx in range(bragg_peaks.shape[0]) + for ry in range(bragg_peaks.shape[1]) ] ) @@ -903,6 +928,9 @@ def plot_diffraction_pattern( ax.set_ylabel("$q_x$ [Å$^{-1}$]") if plot_range_kx_ky is not None: + plot_range_kx_ky = np.array(plot_range_kx_ky) + if plot_range_kx_ky.ndim == 0: + plot_range_kx_ky = np.array((plot_range_kx_ky,plot_range_kx_ky)) ax.set_xlim((-plot_range_kx_ky[0], plot_range_kx_ky[0])) ax.set_ylim((-plot_range_kx_ky[1], plot_range_kx_ky[1])) else: From 32dd2e822e42bac0e39af8cfe3a45dcfd1f4a773 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 13:00:19 -0400 Subject: [PATCH 189/362] partial update to Data cal handling --- py4DSTEM/data/data.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index 0b0bf4bb7..8d20cc360 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -64,24 +64,41 @@ def __init__( calibration = None ): assert(isinstance(self,Node)), "Data instances must inherit from Node" - pass + assert(calibration is None or isinstance(calibration,Calibration)), f"calibration must be None or a Calibration instance, not type {type(calibration)}" + # set up calibration + EMD tree if calibration is None: - if self.root is not None and 'calibration' in self.root.metadata: - pass - else: + if self.root is None: root = Root( name = self.name+"_root" ) root.tree( self ) self.calibration = Calibration() - else: + elif 'calibration' not in self.root.metadata: + self.calibration = Calibration() + else: + pass + elif calibration.root is not None: + if self.root is None: + calibration.root.tree(self) + self.calibration = calibration + elif 'calibration' not in self.root.metadata: + # TODO + self.calibration = calibration + else: + # raises a warning + self.calibration = calibration + + assert(isinstance(calibration,Calibration)), f"`calibration` must be a Calibration, not type {type(calibration)}" - if calibration.root is None: - calibration._root = Root( name = self.name+"_root" ) - calibration.root.tree( self ) + if self.root is not None and 'calibration' in self.root.metadata: + pass else: - calibration.root.tree( self ) - self.calibration = calibration + if calibration.root is None: + calibration._root = Root( name = self.name+"_root" ) + calibration.root.tree( self ) + else: + calibration.root.tree( self ) + self.calibration = calibration # calibration property From be5197cd58135881e23e8dfbf1527d67fc5151d2 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Thu, 13 Jul 2023 11:07:30 -0700 Subject: [PATCH 190/362] commenting out numerical instability introduced in commit a211a97, circa end of April --- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 1e9bd2cbb..8be875b15 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -974,7 +974,7 @@ def _gradient_descent_adjoint( ) # back-transmit - exit_waves *= xp.conj(obj) / xp.abs(obj) ** 2 + exit_waves *= xp.conj(obj) #/ xp.abs(obj) ** 2 if s > 0: # back-propagate @@ -1076,7 +1076,7 @@ def _projection_sets_adjoint( ) # back-transmit - exit_waves_copy *= xp.conj(obj) / xp.abs(obj) ** 2 + exit_waves_copy *= xp.conj(obj) # / xp.abs(obj) ** 2 if s > 0: # back-propagate From 60b7d2795ec2ace0cad21014d2efd433f4f4db42 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 13 Jul 2023 11:20:57 -0700 Subject: [PATCH 191/362] turn off print statements by default --- py4DSTEM/braggvectors/braggvectors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index d3f4a42c5..1d3dee4c0 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -65,7 +65,7 @@ def __init__( Rshape, Qshape, name = 'braggvectors', - verbose = True, + verbose = False, calibration = None ): Custom.__init__(self,name=name) @@ -236,7 +236,7 @@ def setcal( "rotate" : rotate, } if self.verbose: - print('current calstate: ', self.calstate) + print('current calibration state: ', self.calstate) pass From 7a513362647895a8fe039477184eff6e382568dc Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 14:42:49 -0400 Subject: [PATCH 192/362] refactor Data, more robust calibration handling --- py4DSTEM/data/data.py | 58 ++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/py4DSTEM/data/data.py b/py4DSTEM/data/data.py index 8d20cc360..3a7b415db 100644 --- a/py4DSTEM/data/data.py +++ b/py4DSTEM/data/data.py @@ -9,7 +9,16 @@ class Data: """ - Data in py4DSTEM is stored in filetree like representations, e.g. + The purpose of the `Data` class is to ensure calibrations are linked + to data containing class instances, while allowing multiple objects + to share a single Calibration. The calibrations of a Data instance + `data` is accessible as + + >>> data.calibration + + In py4DSTEM, Data containing objects are stored internally in filetree + like representations, defined by the EMD1.0 and `emdfile` specifications, + e.g. Root |--metadata @@ -23,24 +32,30 @@ class Data: | |--etc. : - In a Python interpreter, do + Calibrations are metadata which always live in the root of such a tree. + Running `data.calibration` returns the calibrations from the tree root, + and therefore the same calibration instance is referred to be all objects + in the same tree. The root itself is accessible from any Data instance + as + + >>> data.root + + To examine the tree of a Data instance, in a Python interpreter do >>> data.tree(True) - to display the data tree of Data instance `data`, and + to display the whole data tree, and >>> data.tree() to display the tree of from the current node on, i.e. the branch downstream of `data`. - Every object can access the calibrations which live in the root metadata - of its tree with + Calling >>> data.calibration - which returns the calibrations, or, if none are found, raises a warning - and returns None. + will raise a warning and return None if no root calibrations are found. Some objects should be modified when the calibrations change - these objects must have .calibrate() method, which is called any time relevant @@ -70,35 +85,32 @@ def __init__( # set up calibration + EMD tree if calibration is None: if self.root is None: - root = Root( name = self.name+"_root" ) + root = Root( name=self.name+"_root" ) root.tree( self ) self.calibration = Calibration() elif 'calibration' not in self.root.metadata: self.calibration = Calibration() else: pass - elif calibration.root is not None: + elif calibration.root is None: if self.root is None: - calibration.root.tree(self) + root = Root( name=self.name+"_root" ) + root.tree(self) self.calibration = calibration elif 'calibration' not in self.root.metadata: - # TODO self.calibration = calibration else: - # raises a warning - self.calibration = calibration - - - assert(isinstance(calibration,Calibration)), f"`calibration` must be a Calibration, not type {type(calibration)}" - if self.root is not None and 'calibration' in self.root.metadata: + warnings.warn("A calibration was passed to instantiate a new Data instance, but the instance already has a calibration. The passed calibration *WAS NOT* attached. To attach the new calibration and overwrite the existing calibration, use `data.calibration = new_calibration`") pass - else: - if calibration.root is None: - calibration._root = Root( name = self.name+"_root" ) - calibration.root.tree( self ) - else: - calibration.root.tree( self ) + else: + if self.root is None: + calibration.root.tree(self) + self.calibration = calibration + elif 'calibration' not in self.root.metadata: self.calibration = calibration + warnings.warn("A calibration was passed to instantiate a new Data instance. The Data already had a root but no calibration, and the calibration already exists in a different root. The calibration has been added and now lives in both roots, and can therefore be modified from either place!") + else: + warnings.warn("A calibration was passed to instantiate a new Data instance, however the Data already has a root and calibration, and the calibration already has a root!! The passed calibration *WAS NOT* attached. To attach the new calibration and overwrite the existing calibration, use `data.calibration = new_calibration.") # calibration property From e3d0e29835c33fb35ab3fdb1bf0059b651b365a7 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Mon, 15 May 2023 12:00:21 -0700 Subject: [PATCH 193/362] starting to add parameter class --- py4DSTEM/process/phase/parameter_optimize.py | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 py4DSTEM/process/phase/parameter_optimize.py diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py new file mode 100644 index 000000000..c3a377fb4 --- /dev/null +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -0,0 +1,75 @@ +from tqdm import tqdm +from skopt import gp_minimize +from skopt.space import Real, Integer, Categorical +from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective +from skopt.utils import use_named_args + +from functools import partialmethod +from typing import Union + +from py4DSTEM.process.phase import PtychographicReconstruction + +class PtychographyOptimizer: + """ + doot doot + """ + + def __init__( + self, + reconstruction_type: type[PtychographicReconstruction], + ): + """ + Parameter optimization for ptychographic reconstruction based on Bayesian Optimization + with Gaussian Process. + """ + pass + + def optimize(self,): + pass + + def visualize(self,): + pass + +class OptimizationParameter: + """ + Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer + """ + + def __init__( + self, + name:str, + lower_bound:Union[float,int,bool], + upper_bound:Union[float,int,bool], + initial_value:Union[float,int,bool], + scaling:str='uniform', + space:str="real", + categories:list=[], + ): + + # Check input + space = space.lower() + assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + + scaling = scaling.lower() + assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + + # Get the right scikit-optimize class + space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + param = space_map[space] + + # If a boolean property, the categories are True/False + if space == 'bool': + categories = [True, False] + + # store necessary information + self.name = name + self.initial_value = initial_value + + if param is Categorical: + assert categories is not None, "Empty list of categories!" + self._skopt_param = param(name=name, categories=categories) + else: + self._skopt_param = param(name=name, low=lower_bound, high=upper_bound, prior=scaling,) + + + From 707b2fd8404f5933232907e4bbbf09e10db976bb Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 14:59:04 -0700 Subject: [PATCH 194/362] bayesian optimization for hyperparameter tuning in ptychography --- py4DSTEM/process/phase/parameter_optimize.py | 285 +++++++++++++++---- 1 file changed, 224 insertions(+), 61 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c3a377fb4..c41c611ec 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -3,73 +3,236 @@ from skopt.space import Real, Integer, Categorical from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective from skopt.utils import use_named_args +import matplotlib.pyplot as plt -from functools import partialmethod +from functools import partial from typing import Union -from py4DSTEM.process.phase import PtychographicReconstruction +from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction class PtychographyOptimizer: - """ - doot doot - """ - - def __init__( - self, - reconstruction_type: type[PtychographicReconstruction], - ): - """ - Parameter optimization for ptychographic reconstruction based on Bayesian Optimization - with Gaussian Process. - """ - pass - - def optimize(self,): - pass - - def visualize(self,): - pass + """ + doot doot + """ + + def __init__( + self, + reconstruction_type: type[PhaseReconstruction], + init_args:dict, + preprocess_args:dict, + reconstruction_args:dict, + ): + """ + Parameter optimization for ptychographic reconstruction based on Bayesian Optimization + with Gaussian Process. + """ + + # loop over each argument dictionary and split into static and optimization variables + self._init_static_args, self._init_optimize_args = self._split_static_and_optimization_vars(init_args) + self._preprocess_static_args, self._preprocess_optimize_args = self._split_static_and_optimization_vars(preprocess_args) + self._reconstruction_static_args, self._reconstruction_optimize_args = self._split_static_and_optimization_vars(reconstruction_args) + + # Save list of skopt parameter objects and inital guess + self._parameter_list = [] + self._x0 = [] + for k,v in (self._init_optimize_args|self._preprocess_optimize_args|self._reconstruction_optimize_args).items(): + self._parameter_list.append(v._get(k)) + self._x0.append(v._initial_value) + + self._init_args = init_args + self._preprocess_args = preprocess_args + self._reconstruction_args = reconstruction_args + + self._reconstruction_type = reconstruction_type + + self._set_optimizer_defaults() + + def optimize( + self, + n_calls:int, + n_initial_points:int, + ): + + self._optimization_function = self._get_optimization_function( + self._reconstruction_type, + self._parameter_list, + n_calls, + self._init_static_args, + self._preprocess_static_args, + self._reconstruction_static_args, + self._init_optimize_args, + self._preprocess_optimize_args, + self._reconstruction_optimize_args + ) + + self._skopt_result = gp_minimize( + self._optimization_function, + self._parameter_list, + n_calls = n_calls, + n_initial_points=n_initial_points, + x0 = self._x0 + ) + return self + + def visualize(self,): + if len(self._parameter_list) == 1: + plot_gaussian_process(self._skopt_result) + plt.show() + + plot_convergence(self._skopt_result) + plt.show() + plot_objective(self._skopt_result) + plt.show() + plot_evaluations(self._skopt_result) + plt.show() + return self + + def get_optimized_arguments(self): + init_opt = self._replace_optimized_parameters(self._init_args, self._parameter_list) + prep_opt = self._replace_optimized_parameters(self._preprocess_args, self._parameter_list) + reco_opt = self._replace_optimized_parameters(self._reconstruction_args, self._parameter_list) + + return init_opt, prep_opt, reco_opt + + def _replace_optimized_parameters(self, arg_dict, parameters): + opt_args = {} + for k,v in arg_dict.items(): + # Check for optimization parameters + if isinstance(v,OptimizationParameter): + # Find the right parameter in the list + # There is probably a better way to do this inverse mapping! + for i,p in enumerate(parameters): + if p.name == k: + opt_args[k] = self._skopt_result.x[i] + else: + opt_args[k] = v + return opt_args + + + def _split_static_and_optimization_vars(self,argdict): + static_args = {} + optimization_args = {} + for k,v in argdict.items(): + if isinstance(v,OptimizationParameter): + # unwrap the OptimizationParameter object into a skopt object + optimization_args[k] = v #._get(k) + else: + static_args[k] = v + return static_args, optimization_args + + + def _get_optimization_function( + self, + cls:type[PhaseReconstruction], + parameter_list:list, + n_iterations:int, + init_static_args:dict, + preprocess_static_args:dict, + reconstruct_static_args:dict, + init_optimization_param_names:dict, + preprocess_optimization_param_names:dict, + reconstruct_optimization_param_names:dict): + """ + Wrap the ptychography pipeline into a single function that encapsulates all of the + non-optimization arguments and accepts a concatenated set of keyword arguments. The + wrapper function returns the final error value from the ptychography run. + + parameter_list is a list of skopt Dimension objects + + Both static and optimization args are passed in dictionaries. The values of the + static dictionary are the fixed parameters, and only the keys of the optimization + dictionary are used. + """ + + # Construct partial methods to encapsulate the static parameters + obj = partial(cls,**init_static_args) + prep = partial(cls.preprocess, **preprocess_static_args) + recon = partial(cls.reconstruct, **reconstruct_static_args) + + init_params = list(init_optimization_param_names.keys()) + prep_params = list(preprocess_optimization_param_names.keys()) + reco_params = list(reconstruct_optimization_param_names.keys()) + + # Make a progress bar + pbar = tqdm(total=n_iterations,desc="Optimizing Parameters") + + # Target function for Gaussian process optimization that takes a single + # dict of named parameters and returns the ptycho error metric + @use_named_args(parameter_list) + def f(**kwargs): + init_args = {k:kwargs[k] for k in init_params} + prep_args = {k:kwargs[k] for k in prep_params} + reco_args = {k:kwargs[k] for k in reco_params} + + ptycho = obj(**init_args) + prep(ptycho,**prep_args) + recon(ptycho,**reco_args) + + pbar.update(1) + + return ptycho.error + + return f + + def _set_optimizer_defaults(self): + """ + Set all of the verbose and plotting to False + """ + self._init_static_args['verbose'] = False + + self._preprocess_static_args['plot_center_of_mass'] = False + self._preprocess_static_args['plot_rotation'] = False + self._preprocess_static_args['plot_probe_overlaps'] = False + + self._reconstruction_static_args['progress_bar'] = False + self._reconstruction_static_args['store_iterations'] = False -class OptimizationParameter: - """ - Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer - """ - - def __init__( - self, - name:str, - lower_bound:Union[float,int,bool], - upper_bound:Union[float,int,bool], - initial_value:Union[float,int,bool], - scaling:str='uniform', - space:str="real", - categories:list=[], - ): - - # Check input - space = space.lower() - assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" - - scaling = scaling.lower() - assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" - - # Get the right scikit-optimize class - space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} - param = space_map[space] - - # If a boolean property, the categories are True/False - if space == 'bool': - categories = [True, False] - - # store necessary information - self.name = name - self.initial_value = initial_value - - if param is Categorical: - assert categories is not None, "Empty list of categories!" - self._skopt_param = param(name=name, categories=categories) - else: - self._skopt_param = param(name=name, low=lower_bound, high=upper_bound, prior=scaling,) +class OptimizationParameter: + """ + Wrapper for scikit-optimize Space objects used for convenient calling in the PtyhochraphyOptimizer + """ + + def __init__( + self, + lower_bound:Union[float,int,bool], + upper_bound:Union[float,int,bool], + initial_value:Union[float,int,bool], + scaling:str='uniform', + space:str="real", + categories:list=[], + ): + + # Check input + space = space.lower() + assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + + scaling = scaling.lower() + assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + + # Get the right scikit-optimize class + space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + param = space_map[space] + + # If a boolean property, the categories are True/False + if space == 'bool': + categories = [True, False] + + # store necessary information + self._initial_value = initial_value + self._categories = categories + self._lower_bound = lower_bound + self._upper_bound = upper_bound + self._scaling = scaling + self._param_type = param + + def _get(self,name): + self._name = name + if self._param_type is Categorical: + assert categories is not None, "Empty list of categories!" + self._skopt_param = self._param_type(name=self._name, categories=self._categories) + else: + self._skopt_param = self._param_type(name=self._name, low=self._lower_bound, high=self._upper_bound, prior=self._scaling,) + return self._skopt_param From 1f8357adbc305234f0154ab88b86a7adb41e6148 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 15:23:12 -0700 Subject: [PATCH 195/362] improvements to plotting and progress bar --- py4DSTEM/process/phase/parameter_optimize.py | 35 ++++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c41c611ec..1a5ad768b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -53,7 +53,7 @@ def optimize( n_initial_points:int, ): - self._optimization_function = self._get_optimization_function( + self._optimization_function, pbar = self._get_optimization_function( self._reconstruction_type, self._parameter_list, n_calls, @@ -72,19 +72,32 @@ def optimize( n_initial_points=n_initial_points, x0 = self._x0 ) + + # Finish the tqdm progressbar so subsequent things behave nicely + pbar.close() + return self - def visualize(self,): - if len(self._parameter_list) == 1: + def visualize( + self, + gp_model=True, + convergence=False, + objective=True, + evaluations=False, + ): + if len(self._parameter_list) == 1 and gp_model: plot_gaussian_process(self._skopt_result) plt.show() - plot_convergence(self._skopt_result) - plt.show() - plot_objective(self._skopt_result) - plt.show() - plot_evaluations(self._skopt_result) - plt.show() + if convergence: + plot_convergence(self._skopt_result) + plt.show() + if objective: + plot_objective(self._skopt_result) + plt.show() + if evaluations: + plot_evaluations(self._skopt_result) + plt.show() return self def get_optimized_arguments(self): @@ -154,7 +167,7 @@ def _get_optimization_function( reco_params = list(reconstruct_optimization_param_names.keys()) # Make a progress bar - pbar = tqdm(total=n_iterations,desc="Optimizing Parameters") + pbar = tqdm(total=n_iterations,desc="Optimizing parameters") # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @@ -172,7 +185,7 @@ def f(**kwargs): return ptycho.error - return f + return f, pbar def _set_optimizer_defaults(self): """ From 0fa9e572db4c68e50f27ce5cd3c0620e9a6c1ea5 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 17:35:54 -0700 Subject: [PATCH 196/362] print optimization result --- py4DSTEM/process/phase/parameter_optimize.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 1a5ad768b..8d266e428 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -73,6 +73,10 @@ def optimize( x0 = self._x0 ) + print("Optimized parameters:") + for p,x in zip(self._parameter_list, self._skopt_result.x): + print(f"{p.name}: {x}") + # Finish the tqdm progressbar so subsequent things behave nicely pbar.close() From 86d4b8155421ed653627b5f7edcf76195e2e4880 Mon Sep 17 00:00:00 2001 From: SE Zeltmann Date: Tue, 16 May 2023 18:05:58 -0700 Subject: [PATCH 197/362] format --- py4DSTEM/process/phase/parameter_optimize.py | 181 +++++++++++-------- 1 file changed, 109 insertions(+), 72 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 8d266e428..627cb04c5 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -1,7 +1,12 @@ from tqdm import tqdm from skopt import gp_minimize from skopt.space import Real, Integer, Categorical -from skopt.plots import plot_convergence, plot_gaussian_process, plot_evaluations, plot_objective +from skopt.plots import ( + plot_convergence, + plot_gaussian_process, + plot_evaluations, + plot_objective, +) from skopt.utils import use_named_args import matplotlib.pyplot as plt @@ -10,6 +15,7 @@ from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction + class PtychographyOptimizer: """ doot doot @@ -18,24 +24,37 @@ class PtychographyOptimizer: def __init__( self, reconstruction_type: type[PhaseReconstruction], - init_args:dict, - preprocess_args:dict, - reconstruction_args:dict, - ): + init_args: dict, + preprocess_args: dict, + reconstruction_args: dict, + ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization - with Gaussian Process. + with Gaussian Process. """ - + # loop over each argument dictionary and split into static and optimization variables - self._init_static_args, self._init_optimize_args = self._split_static_and_optimization_vars(init_args) - self._preprocess_static_args, self._preprocess_optimize_args = self._split_static_and_optimization_vars(preprocess_args) - self._reconstruction_static_args, self._reconstruction_optimize_args = self._split_static_and_optimization_vars(reconstruction_args) + ( + self._init_static_args, + self._init_optimize_args, + ) = self._split_static_and_optimization_vars(init_args) + ( + self._preprocess_static_args, + self._preprocess_optimize_args, + ) = self._split_static_and_optimization_vars(preprocess_args) + ( + self._reconstruction_static_args, + self._reconstruction_optimize_args, + ) = self._split_static_and_optimization_vars(reconstruction_args) # Save list of skopt parameter objects and inital guess self._parameter_list = [] self._x0 = [] - for k,v in (self._init_optimize_args|self._preprocess_optimize_args|self._reconstruction_optimize_args).items(): + for k, v in ( + self._init_optimize_args + | self._preprocess_optimize_args + | self._reconstruction_optimize_args + ).items(): self._parameter_list.append(v._get(k)) self._x0.append(v._initial_value) @@ -49,10 +68,9 @@ def __init__( def optimize( self, - n_calls:int, - n_initial_points:int, - ): - + n_calls: int, + n_initial_points: int, + ): self._optimization_function, pbar = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -62,19 +80,19 @@ def optimize( self._reconstruction_static_args, self._init_optimize_args, self._preprocess_optimize_args, - self._reconstruction_optimize_args - ) + self._reconstruction_optimize_args, + ) self._skopt_result = gp_minimize( self._optimization_function, self._parameter_list, - n_calls = n_calls, + n_calls=n_calls, n_initial_points=n_initial_points, - x0 = self._x0 + x0=self._x0, ) print("Optimized parameters:") - for p,x in zip(self._parameter_list, self._skopt_result.x): + for p, x in zip(self._parameter_list, self._skopt_result.x): print(f"{p.name}: {x}") # Finish the tqdm progressbar so subsequent things behave nicely @@ -105,50 +123,55 @@ def visualize( return self def get_optimized_arguments(self): - init_opt = self._replace_optimized_parameters(self._init_args, self._parameter_list) - prep_opt = self._replace_optimized_parameters(self._preprocess_args, self._parameter_list) - reco_opt = self._replace_optimized_parameters(self._reconstruction_args, self._parameter_list) + init_opt = self._replace_optimized_parameters( + self._init_args, self._parameter_list + ) + prep_opt = self._replace_optimized_parameters( + self._preprocess_args, self._parameter_list + ) + reco_opt = self._replace_optimized_parameters( + self._reconstruction_args, self._parameter_list + ) return init_opt, prep_opt, reco_opt def _replace_optimized_parameters(self, arg_dict, parameters): opt_args = {} - for k,v in arg_dict.items(): + for k, v in arg_dict.items(): # Check for optimization parameters - if isinstance(v,OptimizationParameter): + if isinstance(v, OptimizationParameter): # Find the right parameter in the list # There is probably a better way to do this inverse mapping! - for i,p in enumerate(parameters): + for i, p in enumerate(parameters): if p.name == k: opt_args[k] = self._skopt_result.x[i] else: opt_args[k] = v return opt_args - - def _split_static_and_optimization_vars(self,argdict): + def _split_static_and_optimization_vars(self, argdict): static_args = {} optimization_args = {} - for k,v in argdict.items(): - if isinstance(v,OptimizationParameter): + for k, v in argdict.items(): + if isinstance(v, OptimizationParameter): # unwrap the OptimizationParameter object into a skopt object - optimization_args[k] = v #._get(k) + optimization_args[k] = v # ._get(k) else: static_args[k] = v return static_args, optimization_args - def _get_optimization_function( self, - cls:type[PhaseReconstruction], - parameter_list:list, - n_iterations:int, - init_static_args:dict, - preprocess_static_args:dict, - reconstruct_static_args:dict, - init_optimization_param_names:dict, - preprocess_optimization_param_names:dict, - reconstruct_optimization_param_names:dict): + cls: type[PhaseReconstruction], + parameter_list: list, + n_iterations: int, + init_static_args: dict, + preprocess_static_args: dict, + reconstruct_static_args: dict, + init_optimization_param_names: dict, + preprocess_optimization_param_names: dict, + reconstruct_optimization_param_names: dict, + ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the non-optimization arguments and accepts a concatenated set of keyword arguments. The @@ -158,11 +181,11 @@ def _get_optimization_function( Both static and optimization args are passed in dictionaries. The values of the static dictionary are the fixed parameters, and only the keys of the optimization - dictionary are used. + dictionary are used. """ # Construct partial methods to encapsulate the static parameters - obj = partial(cls,**init_static_args) + obj = partial(cls, **init_static_args) prep = partial(cls.preprocess, **preprocess_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) @@ -171,38 +194,38 @@ def _get_optimization_function( reco_params = list(reconstruct_optimization_param_names.keys()) # Make a progress bar - pbar = tqdm(total=n_iterations,desc="Optimizing parameters") + pbar = tqdm(total=n_iterations, desc="Optimizing parameters") # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) def f(**kwargs): - init_args = {k:kwargs[k] for k in init_params} - prep_args = {k:kwargs[k] for k in prep_params} - reco_args = {k:kwargs[k] for k in reco_params} + init_args = {k: kwargs[k] for k in init_params} + prep_args = {k: kwargs[k] for k in prep_params} + reco_args = {k: kwargs[k] for k in reco_params} ptycho = obj(**init_args) - prep(ptycho,**prep_args) - recon(ptycho,**reco_args) + prep(ptycho, **prep_args) + recon(ptycho, **reco_args) pbar.update(1) return ptycho.error - + return f, pbar def _set_optimizer_defaults(self): """ Set all of the verbose and plotting to False """ - self._init_static_args['verbose'] = False + self._init_static_args["verbose"] = False - self._preprocess_static_args['plot_center_of_mass'] = False - self._preprocess_static_args['plot_rotation'] = False - self._preprocess_static_args['plot_probe_overlaps'] = False + self._preprocess_static_args["plot_center_of_mass"] = False + self._preprocess_static_args["plot_rotation"] = False + self._preprocess_static_args["plot_probe_overlaps"] = False - self._reconstruction_static_args['progress_bar'] = False - self._reconstruction_static_args['store_iterations'] = False + self._reconstruction_static_args["progress_bar"] = False + self._reconstruction_static_args["store_iterations"] = False class OptimizationParameter: @@ -212,27 +235,36 @@ class OptimizationParameter: def __init__( self, - lower_bound:Union[float,int,bool], - upper_bound:Union[float,int,bool], - initial_value:Union[float,int,bool], - scaling:str='uniform', - space:str="real", - categories:list=[], - ): - + lower_bound: Union[float, int, bool], + upper_bound: Union[float, int, bool], + initial_value: Union[float, int, bool], + scaling: str = "uniform", + space: str = "real", + categories: list = [], + ): # Check input space = space.lower() - assert space in ("real","integer","bool","categorical"), f"Unknown Parameter type: {space}" + assert space in ( + "real", + "integer", + "bool", + "categorical", + ), f"Unknown Parameter type: {space}" scaling = scaling.lower() assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" # Get the right scikit-optimize class - space_map = {'real':Real, 'integer':Integer, 'bool':Categorical, 'categorical':Categorical} + space_map = { + "real": Real, + "integer": Integer, + "bool": Categorical, + "categorical": Categorical, + } param = space_map[space] # If a boolean property, the categories are True/False - if space == 'bool': + if space == "bool": categories = [True, False] # store necessary information @@ -243,13 +275,18 @@ def __init__( self._scaling = scaling self._param_type = param - def _get(self,name): + def _get(self, name): self._name = name if self._param_type is Categorical: assert categories is not None, "Empty list of categories!" - self._skopt_param = self._param_type(name=self._name, categories=self._categories) + self._skopt_param = self._param_type( + name=self._name, categories=self._categories + ) else: - self._skopt_param = self._param_type(name=self._name, low=self._lower_bound, high=self._upper_bound, prior=self._scaling,) + self._skopt_param = self._param_type( + name=self._name, + low=self._lower_bound, + high=self._upper_bound, + prior=self._scaling, + ) return self._skopt_param - - From b445ac3f42110f64c5677af14980e7c053298e3d Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Thu, 18 May 2023 15:06:19 -0700 Subject: [PATCH 198/362] add affine transform to bayesian optimize --- py4DSTEM/process/phase/parameter_optimize.py | 73 +++++++++++++++----- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 627cb04c5..dbecdb22c 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -9,11 +9,13 @@ ) from skopt.utils import use_named_args import matplotlib.pyplot as plt +import numpy as np from functools import partial from typing import Union from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction +from py4DSTEM.process.phase.utils import AffineTransform class PtychographyOptimizer: @@ -25,6 +27,7 @@ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, + affine_args:dict, preprocess_args: dict, reconstruction_args: dict, ): @@ -38,6 +41,10 @@ def __init__( self._init_static_args, self._init_optimize_args, ) = self._split_static_and_optimization_vars(init_args) + ( + self._affine_static_args, + self._affine_optimize_args, + ) = self._split_static_and_optimization_vars(affine_args) ( self._preprocess_static_args, self._preprocess_optimize_args, @@ -52,6 +59,7 @@ def __init__( self._x0 = [] for k, v in ( self._init_optimize_args + | self._affine_optimize_args | self._preprocess_optimize_args | self._reconstruction_optimize_args ).items(): @@ -59,6 +67,7 @@ def __init__( self._x0.append(v._initial_value) self._init_args = init_args + self._affine_args = affine_args self._preprocess_args = preprocess_args self._reconstruction_args = reconstruction_args @@ -71,24 +80,34 @@ def optimize( n_calls: int, n_initial_points: int, ): - self._optimization_function, pbar = self._get_optimization_function( + self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, n_calls, self._init_static_args, + self._affine_static_args, self._preprocess_static_args, self._reconstruction_static_args, self._init_optimize_args, + self._affine_optimize_args, self._preprocess_optimize_args, self._reconstruction_optimize_args, ) + # Make a progress bar + pbar = tqdm(total=n_calls, desc="Optimizing parameters") + # We need to wrap the callback because if it returns a value + # the optimizer breaks its loop + def callback(*args,**kwargs): + pbar.update(1) + self._skopt_result = gp_minimize( self._optimization_function, self._parameter_list, n_calls=n_calls, n_initial_points=n_initial_points, x0=self._x0, + callback=callback, ) print("Optimized parameters:") @@ -107,10 +126,9 @@ def visualize( objective=True, evaluations=False, ): - if len(self._parameter_list) == 1 and gp_model: + if (len(self._parameter_list) == 1) and gp_model: plot_gaussian_process(self._skopt_result) plt.show() - if convergence: plot_convergence(self._skopt_result) plt.show() @@ -126,6 +144,13 @@ def get_optimized_arguments(self): init_opt = self._replace_optimized_parameters( self._init_args, self._parameter_list ) + affine_opt = self._replace_optimized_parameters( + self._affine_args, self._parameter_list + ) + affine_transform = partial(AffineTransform, **self._affine_static_args)(**affine_opt) + scan_positions = self._get_scan_positions(affine_transform, init_opt['datacube']) + init_opt['initial_scan_positions'] = scan_positions + prep_opt = self._replace_optimized_parameters( self._preprocess_args, self._parameter_list ) @@ -154,23 +179,32 @@ def _split_static_and_optimization_vars(self, argdict): optimization_args = {} for k, v in argdict.items(): if isinstance(v, OptimizationParameter): - # unwrap the OptimizationParameter object into a skopt object - optimization_args[k] = v # ._get(k) + optimization_args[k] = v else: static_args[k] = v return static_args, optimization_args + def _get_scan_positions(self, affine_transform, dataset): + R_pixel_size = dataset.calibration.get_R_pixel_size() + x,y = np.arange(dataset.R_Nx)*R_pixel_size, np.arange(dataset.R_Ny)*R_pixel_size + x, y = np.meshgrid(x, y, indexing="ij") + scan_positions = np.stack((x.ravel(),y.ravel()),axis=1) + scan_positions = scan_positions @ affine_transform.asarray() + return scan_positions + def _get_optimization_function( self, cls: type[PhaseReconstruction], parameter_list: list, n_iterations: int, init_static_args: dict, + affine_static_args:dict, preprocess_static_args: dict, reconstruct_static_args: dict, - init_optimization_param_names: dict, - preprocess_optimization_param_names: dict, - reconstruct_optimization_param_names: dict, + init_optimization_params: dict, + affine_optimization_params: dict, + preprocess_optimization_params: dict, + reconstruct_optimization_params: dict, ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the @@ -186,33 +220,38 @@ def _get_optimization_function( # Construct partial methods to encapsulate the static parameters obj = partial(cls, **init_static_args) + affine = partial(AffineTransform, **affine_static_args) prep = partial(cls.preprocess, **preprocess_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) - init_params = list(init_optimization_param_names.keys()) - prep_params = list(preprocess_optimization_param_names.keys()) - reco_params = list(reconstruct_optimization_param_names.keys()) - - # Make a progress bar - pbar = tqdm(total=n_iterations, desc="Optimizing parameters") + init_params = list(init_optimization_params.keys()) + afft_params = list(affine_optimization_params.keys()) + prep_params = list(preprocess_optimization_params.keys()) + reco_params = list(reconstruct_optimization_params.keys()) # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) def f(**kwargs): init_args = {k: kwargs[k] for k in init_params} + afft_args = {k: kwargs[k] for k in afft_params} prep_args = {k: kwargs[k] for k in prep_params} reco_args = {k: kwargs[k] for k in reco_params} + # Create affine transform object + tr = affine(**afft_args) + # Apply affine transform to pixel grid, using the + # calibrations lifted from the dataset + dataset = init_static_args['datacube'] + init_args['initial_scan_positions'] = self._get_scan_positions(tr, dataset) + ptycho = obj(**init_args) prep(ptycho, **prep_args) recon(ptycho, **reco_args) - pbar.update(1) - return ptycho.error - return f, pbar + return f def _set_optimizer_defaults(self): """ From 1f5051259440f39bd0c205edac9136ef2de2ac64 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Thu, 18 May 2023 15:16:09 -0700 Subject: [PATCH 199/362] bugfix from linter --- py4DSTEM/process/phase/parameter_optimize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index dbecdb22c..dffa991ab 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -317,7 +317,7 @@ def __init__( def _get(self, name): self._name = name if self._param_type is Categorical: - assert categories is not None, "Empty list of categories!" + assert self._categories is not None, "Empty list of categories!" self._skopt_param = self._param_type( name=self._name, categories=self._categories ) From 1840466e43730278a136f38cf72ab9298c006c87 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Fri, 19 May 2023 14:51:52 -0700 Subject: [PATCH 200/362] add documentation and format --- py4DSTEM/process/phase/parameter_optimize.py | 120 ++++++++++++++++--- 1 file changed, 106 insertions(+), 14 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index dffa991ab..987ffedef 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -20,20 +20,48 @@ class PtychographyOptimizer: """ - doot doot + Optimize ptychographic hyperparameters with Bayesian Optimization of a + Gaussian process. Any of the arguments to the ptychographic + init-preprocess-reconstruct pipeline can be optimized over (including + boolean or other flag options) """ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, - affine_args:dict, + affine_args: dict, preprocess_args: dict, reconstruction_args: dict, ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization with Gaussian Process. + + Usage + ----- + Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial + scan positions), preprocess, and reconstruct are required. For parameters not optimized + over, the value in the dictionary is used. To optimize a parameter, instead pass an + OptimizationParameter object inside the dictionary to specify the bounds, initial guess, + and type of parameter. Calling optimize will then run the optimization simultaneously + over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments + to return a set of dictionaries where the OptimizationParameter objects have been replaced + with the optimal values. These can then be modified for running a full reconstruction. + + Parameters + ---------- + reconstruction_type: class + Type of ptychographic reconstruction to perform + init_args: dict + Keyword arguments passed to the __init__ method of the reconstruction class + affine_args: dict + Keyword arguments passed to AffineTransform. The transform is applied to the initial + scan positions. + preprocess_args: dict + Keyword arguments passed to the preprocess method the reconstruction object + reconstruction_args: dict + Keyword arguments passed to the reconstruct method the the reconstruction object """ # loop over each argument dictionary and split into static and optimization variables @@ -79,7 +107,22 @@ def optimize( self, n_calls: int, n_initial_points: int, + **skopt_kwargs: dict, ): + """ + Run optimizer + + Parameters + ---------- + n_calls: int + Number of times to run ptychographic reconstruction + n_initial_points: int + Number of uniformly spaced trial points to test before + beginning Bayesian optimization (must be less than n_calls) + skopt_kwargs: dict + Additional arguments to be passed to skopt.gp_minimize + + """ self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -96,9 +139,10 @@ def optimize( # Make a progress bar pbar = tqdm(total=n_calls, desc="Optimizing parameters") + # We need to wrap the callback because if it returns a value # the optimizer breaks its loop - def callback(*args,**kwargs): + def callback(*args, **kwargs): pbar.update(1) self._skopt_result = gp_minimize( @@ -108,6 +152,7 @@ def callback(*args,**kwargs): n_initial_points=n_initial_points, x0=self._x0, callback=callback, + **skopt_kwargs, ) print("Optimized parameters:") @@ -126,6 +171,20 @@ def visualize( objective=True, evaluations=False, ): + """ + Visualize optimization results + + Parameters + ---------- + gp_model: bool + Display fitted Gaussian process model (only available for 1-dimensional problem) + convergence: bool + Display convergence history + objective: bool + Display GP objective function and partial dependence plots + evaluations: bool + Display histograms of sampled points + """ if (len(self._parameter_list) == 1) and gp_model: plot_gaussian_process(self._skopt_result) plt.show() @@ -141,15 +200,29 @@ def visualize( return self def get_optimized_arguments(self): + """ + Get argument dictionaries containing optimized hyperparameters + + Returns + ------- + init_opt, prep_opt, reco_opt: dicts + Dictionaries of arguments to __init__, preprocess, and reconstruct + where the OptimizationParameter items have been replaced with the optimal + values obtained from the optimizer + """ init_opt = self._replace_optimized_parameters( self._init_args, self._parameter_list ) affine_opt = self._replace_optimized_parameters( self._affine_args, self._parameter_list ) - affine_transform = partial(AffineTransform, **self._affine_static_args)(**affine_opt) - scan_positions = self._get_scan_positions(affine_transform, init_opt['datacube']) - init_opt['initial_scan_positions'] = scan_positions + affine_transform = partial(AffineTransform, **self._affine_static_args)( + **affine_opt + ) + scan_positions = self._get_scan_positions( + affine_transform, init_opt["datacube"] + ) + init_opt["initial_scan_positions"] = scan_positions prep_opt = self._replace_optimized_parameters( self._preprocess_args, self._parameter_list @@ -186,9 +259,12 @@ def _split_static_and_optimization_vars(self, argdict): def _get_scan_positions(self, affine_transform, dataset): R_pixel_size = dataset.calibration.get_R_pixel_size() - x,y = np.arange(dataset.R_Nx)*R_pixel_size, np.arange(dataset.R_Ny)*R_pixel_size + x, y = ( + np.arange(dataset.R_Nx) * R_pixel_size, + np.arange(dataset.R_Ny) * R_pixel_size, + ) x, y = np.meshgrid(x, y, indexing="ij") - scan_positions = np.stack((x.ravel(),y.ravel()),axis=1) + scan_positions = np.stack((x.ravel(), y.ravel()), axis=1) scan_positions = scan_positions @ affine_transform.asarray() return scan_positions @@ -198,7 +274,7 @@ def _get_optimization_function( parameter_list: list, n_iterations: int, init_static_args: dict, - affine_static_args:dict, + affine_static_args: dict, preprocess_static_args: dict, reconstruct_static_args: dict, init_optimization_params: dict, @@ -240,10 +316,10 @@ def f(**kwargs): # Create affine transform object tr = affine(**afft_args) - # Apply affine transform to pixel grid, using the + # Apply affine transform to pixel grid, using the # calibrations lifted from the dataset - dataset = init_static_args['datacube'] - init_args['initial_scan_positions'] = self._get_scan_positions(tr, dataset) + dataset = init_static_args["datacube"] + init_args["initial_scan_positions"] = self._get_scan_positions(tr, dataset) ptycho = obj(**init_args) prep(ptycho, **prep_args) @@ -274,13 +350,29 @@ class OptimizationParameter: def __init__( self, - lower_bound: Union[float, int, bool], - upper_bound: Union[float, int, bool], initial_value: Union[float, int, bool], + lower_bound: Union[float, int, bool] = None, + upper_bound: Union[float, int, bool] = None, scaling: str = "uniform", space: str = "real", categories: list = [], ): + """ + Wrapper for scikit-optimize Space objects used as inputs to PtychographyOptimizer + + Parameters + ---------- + initial_value: + Initial value, used for first evaluation in optimizer + lower_bound, upper_bound: + Bounds on real or integer variables (not needed for bool or categorical) + scaling: str + Prior knowledge on sensitivity of the variable. Can be 'uniform' or 'log-uniform' + space: str + Type of variable. Can be 'real', 'integer', 'bool', or 'categorical' + categories: list + List of options for Categorical parameter + """ # Check input space = space.lower() assert space in ( From 6ae97a3ebc9a7accc0f62f27d5cc0bb1a4f0669e Mon Sep 17 00:00:00 2001 From: Steve Zeltmann Date: Fri, 19 May 2023 14:57:52 -0700 Subject: [PATCH 201/362] add isotropic expansion option to AffineTransform --- py4DSTEM/process/phase/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index bb11db7d4..5bc44d95a 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -644,6 +644,8 @@ class AffineTransform: x-translation t1: float y-translation + dilation: float + Isotropic expansion (multiplies scale0 and scale1) """ def __init__( @@ -654,9 +656,10 @@ def __init__( angle: float = 0.0, t0: float = 0.0, t1: float = 0.0, + dilation: float = 1.0, ): - self.scale0 = scale0 - self.scale1 = scale1 + self.scale0 = scale0 * dilation + self.scale1 = scale1 * dilation self.shear1 = shear1 self.angle = angle self.t0 = t0 From f78342ec6ae2715e495d88af28df23dc16bf0dc5 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Wed, 17 May 2023 11:32:12 -0400 Subject: [PATCH 202/362] fix calibration move --- py4DSTEM/preprocess/preprocess.py | 3 +++ py4DSTEM/process/phase/iterative_base_class.py | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 343c20895..16dd64555 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -643,6 +643,7 @@ def resample_data_diffraction( datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom @@ -674,6 +675,8 @@ def resample_data_diffraction( resampling_factor = np.concatenate(((1, 1), resampling_factor)) datacube.data = zoom(datacube.data, resampling_factor, order=1) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor[2]) + else: raise ValueError( f"'method' needs to be one of 'bilinear' or 'fourier', not {method}." diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index e3dfa1cd7..bf9c6b2f9 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -194,8 +194,7 @@ def _preprocess_datacube_and_vacuum_probe( output_size=diffraction_intensities_shape, force_nonnegative=True, ) - datacube.calibration.set_Q_pixel_size(Q_pixel_size / resampling_factor_x) - + if probe_roi_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = probe_roi_shape From 0461c3f5c39fc14194aef407526da8679f4f7c86 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sun, 4 Jun 2023 11:07:46 -0400 Subject: [PATCH 203/362] add calibration overrides to ptycho base class --- .../process/phase/iterative_base_class.py | 164 +++++++++++------- 1 file changed, 104 insertions(+), 60 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index bf9c6b2f9..4acb85cd5 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -221,6 +221,9 @@ def _extract_intensities_and_calibrations_from_datacube( self, datacube: DataCube, require_calibrations: bool = False, + force_scan_sampling: Optional[float] = None, + force_angular_sampling: Optional[float] = None, + force_reciprocal_sampling: Optional[float] = None, ): """ Method to extract intensities and calibrations from datacube. @@ -231,6 +234,12 @@ def _extract_intensities_and_calibrations_from_datacube( Input 4D diffraction pattern intensities require_calibrations: bool If False, warning is issued instead of raising an error + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 Assigns -------- @@ -276,80 +285,115 @@ def _extract_intensities_and_calibrations_from_datacube( reciprocal_space_units = calibration.get_Q_pixel_units() # Real-space - if real_space_units == "pixels": - if require_calibrations: - raise ValueError("Real-space calibrations must be given in 'A'") - - warnings.warn( - ( - "Iterative reconstruction will not be quantitative unless you specify " - "real-space calibrations in 'A'" - ), - UserWarning, - ) + if force_scan_sampling is not None: + self._scan_sampling = (force_scan_sampling, force_scan_sampling) + self._scan_units = "A" + else: + if real_space_units == "pixels": + if require_calibrations: + raise ValueError("Real-space calibrations must be given in 'A'") - self._scan_sampling = (1.0, 1.0) - self._scan_units = ("pixels",) * 2 + warnings.warn( + ( + "Iterative reconstruction will not be quantitative unless you specify " + "real-space calibrations in 'A'" + ), + UserWarning, + ) - elif real_space_units == "A": - self._scan_sampling = (calibration.get_R_pixel_size(),) * 2 - self._scan_units = ("A",) * 2 - elif real_space_units == "nm": - self._scan_sampling = (calibration.get_R_pixel_size() * 10,) * 2 - self._scan_units = ("A",) * 2 - else: - raise ValueError( - f"Real-space calibrations must be given in 'A', not {real_space_units}" - ) + self._scan_sampling = (1.0, 1.0) + self._scan_units = ("pixels",) * 2 - # Reciprocal-space - if reciprocal_space_units == "pixels": - if require_calibrations: + elif real_space_units == "A": + self._scan_sampling = (calibration.get_R_pixel_size(),) * 2 + self._scan_units = ("A",) * 2 + elif real_space_units == "nm": + self._scan_sampling = (calibration.get_R_pixel_size() * 10,) * 2 + self._scan_units = ("A",) * 2 + else: raise ValueError( - "Reciprocal-space calibrations must be given in in 'A^-1' or 'mrad'" + f"Real-space calibrations must be given in 'A', not {real_space_units}" ) - warnings.warn( - ( - "Iterative reconstruction will not be quantitative unless you specify " - "appropriate reciprocal-space calibrations" - ), - UserWarning, + # Reciprocal-space + if force_angular_sampling is not None or force_reciprocal_sampling is not None: + # there is no xor keyword in Python! + angular = force_angular_sampling is not None + reciprocal = force_reciprocal_sampling is not None + assert (angular and not reciprocal) or (not angular and reciprocal), ( + "Only one of angular or reciprocal calibration can be forced!" ) - self._angular_sampling = (1.0, 1.0) - self._angular_units = ("pixels",) * 2 - self._reciprocal_sampling = (1.0, 1.0) - self._reciprocal_units = ("pixels",) * 2 - - elif reciprocal_space_units == "A^-1": - reciprocal_size = calibration.get_Q_pixel_size() - self._reciprocal_sampling = (reciprocal_size,) * 2 - self._reciprocal_units = ("A^-1",) * 2 - - if self._energy is not None: - self._angular_sampling = ( - reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, - ) * 2 + # angular calibration specified + if angular: + self._angular_sampling = (force_angular_sampling,) * 2 self._angular_units = ("mrad",) * 2 - elif reciprocal_space_units == "mrad": - angular_size = calibration.get_Q_pixel_size() - self._angular_sampling = (angular_size,) * 2 - self._angular_units = ("mrad",) * 2 + if self._energy is not None: + self._reciprocal_sampling = ( + force_angular_sampling / electron_wavelength_angstrom(self._energy) / 1e3, + ) * 2 + self._reciprocal_units = ("A^-1",) * 2 - if self._energy is not None: - self._reciprocal_sampling = ( - angular_size / electron_wavelength_angstrom(self._energy) / 1e3, - ) * 2 + # reciprocal calibration specified + if reciprocal: + self._reciprocal_sampling = (force_reciprocal_sampling,) * 2 self._reciprocal_units = ("A^-1",) * 2 + + if self._energy is not None: + self._angular_sampling = ( + force_reciprocal_sampling * electron_wavelength_angstrom(self._energy) * 1e3, + ) * 2 + self._angular_units = ("mrad",) * 2 + else: - raise ValueError( - ( - "Reciprocal-space calibrations must be given in 'A^-1' or 'mrad', " - f"not {reciprocal_space_units}" + if reciprocal_space_units == "pixels": + if require_calibrations: + raise ValueError( + "Reciprocal-space calibrations must be given in in 'A^-1' or 'mrad'" + ) + + warnings.warn( + ( + "Iterative reconstruction will not be quantitative unless you specify " + "appropriate reciprocal-space calibrations" + ), + UserWarning, + ) + + self._angular_sampling = (1.0, 1.0) + self._angular_units = ("pixels",) * 2 + self._reciprocal_sampling = (1.0, 1.0) + self._reciprocal_units = ("pixels",) * 2 + + elif reciprocal_space_units == "A^-1": + reciprocal_size = calibration.get_Q_pixel_size() + self._reciprocal_sampling = (reciprocal_size,) * 2 + self._reciprocal_units = ("A^-1",) * 2 + + if self._energy is not None: + self._angular_sampling = ( + reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, + ) * 2 + self._angular_units = ("mrad",) * 2 + + elif reciprocal_space_units == "mrad": + angular_size = calibration.get_Q_pixel_size() + self._angular_sampling = (angular_size,) * 2 + self._angular_units = ("mrad",) * 2 + + if self._energy is not None: + self._reciprocal_sampling = ( + angular_size / electron_wavelength_angstrom(self._energy) / 1e3, + ) * 2 + self._reciprocal_units = ("A^-1",) * 2 + else: + raise ValueError( + ( + "Reciprocal-space calibrations must be given in 'A^-1' or 'mrad', " + f"not {reciprocal_space_units}" + ) ) - ) return intensities From fb3383e153b52d992b348ce961b102e9bfcc976e Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 5 Jun 2023 15:04:52 -0400 Subject: [PATCH 204/362] bugfix and document previous commit --- py4DSTEM/preprocess/preprocess.py | 8 +++++++- .../process/phase/iterative_base_class.py | 6 +++--- .../iterative_singleslice_ptychography.py | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 16dd64555..9bb52cd46 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -640,10 +640,16 @@ def resample_data_diffraction( ) resampling_factor = resampling_factor[0] + old_size = datacube.data.shape + datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + + if not resampling_factor: + resampling_factor = old_size[2] / output_size[0] + if datacube.calibration.get_Q_pixel_size() is not None: + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 4acb85cd5..c383598b2 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -221,9 +221,9 @@ def _extract_intensities_and_calibrations_from_datacube( self, datacube: DataCube, require_calibrations: bool = False, - force_scan_sampling: Optional[float] = None, - force_angular_sampling: Optional[float] = None, - force_reciprocal_sampling: Optional[float] = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, ): """ Method to extract intensities and calibrations from datacube. diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 3efe50810..cfac995fb 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -91,6 +91,7 @@ def __init__( energy: float, datacube: DataCube = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -156,6 +157,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -180,6 +182,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -229,6 +234,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -273,8 +284,16 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + ( self._com_measured_x, self._com_measured_y, From dfde3e5cc202c74be963bae67b8af1a9d47e8db0 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 3 Jun 2023 12:13:26 -0400 Subject: [PATCH 205/362] backtracking in DPC --- py4DSTEM/process/phase/iterative_dpc.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index ca0cdf10d..334856a2f 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -603,6 +603,7 @@ def reconstruct( max_iter: int = 64, step_size: float = None, stopping_criterion: float = 1e-6, + backtrack: bool = True, progress_bar: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, @@ -667,6 +668,8 @@ def reconstruct( self._step_size = step_size if step_size is not None else 0.5 self._padded_phase_object = self._padded_phase_object_initial.copy() + previous_iteration = self._padded_phase_object.copy() + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -689,10 +692,19 @@ def reconstruct( break # forward operator - com_dx, com_dy, self.error, self._step_size = self._forward( + com_dx, com_dy, new_error, self._step_size = self._forward( self._padded_phase_object, mask, mask_inv, self.error, self._step_size ) + # if the error went up after the previous step, go back to the step + # before the error rose and continue with the halved step size + if (new_error > self.error) and backtrack: + self._padded_phase_object = previous_iteration + print(f"Iteration {a0}, step reduced to {self._step_size}") + continue + self.error = new_error + previous_iteration = self._padded_phase_object.copy() + # adjoint operator phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) From fc33b47f1138aa00effafa5cec16f465ea956657 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 3 Jun 2023 12:16:40 -0400 Subject: [PATCH 206/362] DPC backtrack docs --- py4DSTEM/process/phase/iterative_dpc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 334856a2f..f511f4cd7 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -625,6 +625,10 @@ def reconstruct( Reconstruction update step size stopping_criterion: float, optional step_size below which reconstruction exits + backtrack: bool, optional + If True, steps that increase the error metric are rejected + and iteration continues with a reduced step size from the + previous iteration progress_bar: bool, optional If True, reconstruction progress bar will be printed gaussian_filter_sigma: float, optional From feef290d7fa6d8796948a2c2ec2db03d0bc7659d Mon Sep 17 00:00:00 2001 From: Stephanie Ribet <55254539+smribet@users.noreply.github.com> Date: Wed, 7 Jun 2023 13:58:36 -0700 Subject: [PATCH 207/362] step size reorg --- py4DSTEM/process/phase/iterative_dpc.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index f511f4cd7..113a7ea4e 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -421,9 +421,6 @@ def _forward( xp.mean(self._com_x.ravel() ** 2 + self._com_y.ravel() ** 2) ) - if new_error > error: - step_size /= 2 - return obj_dx, obj_dy, new_error, step_size def _adjoint( @@ -671,9 +668,7 @@ def reconstruct( self.error = np.inf self._step_size = step_size if step_size is not None else 0.5 self._padded_phase_object = self._padded_phase_object_initial.copy() - - previous_iteration = self._padded_phase_object.copy() - + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -694,7 +689,9 @@ def reconstruct( ): if self._step_size < stopping_criterion: break - + + previous_iteration = self._padded_phase_object.copy() + # forward operator com_dx, com_dy, new_error, self._step_size = self._forward( self._padded_phase_object, mask, mask_inv, self.error, self._step_size @@ -704,10 +701,10 @@ def reconstruct( # before the error rose and continue with the halved step size if (new_error > self.error) and backtrack: self._padded_phase_object = previous_iteration + self._step_size /= 2 print(f"Iteration {a0}, step reduced to {self._step_size}") continue self.error = new_error - previous_iteration = self._padded_phase_object.copy() # adjoint operator phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) From a099124ecfa3ce710e00176413cf2735e364ac4e Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 8 Jun 2023 10:04:25 -0700 Subject: [PATCH 208/362] anti gridding filter --- py4DSTEM/process/phase/iterative_dpc.py | 81 +++++++++++++++++++------ 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 113a7ea4e..949ae0d45 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -338,13 +338,13 @@ def preprocess( padded_object_shape = np.round( np.array(self._grid_scan_shape) * padding_factor ).astype("int") - self._padded_phase_object = xp.zeros(padded_object_shape, dtype=xp.float32) + self._padded_object_phase = xp.zeros(padded_object_shape, dtype=xp.float32) if self._object_phase is not None: - self._padded_phase_object[ + self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ] = xp.asarray(self._object_phase, dtype=xp.float32) - self._padded_phase_object_initial = self._padded_phase_object.copy() + self._padded_object_phase_initial = self._padded_object_phase.copy() # Fourier coordinates and operators kx = xp.fft.fftfreq(padded_object_shape[0], d=self._scan_sampling[0]) @@ -479,7 +479,7 @@ def _update( Returns -------- - updated_padded_phase_object: np.ndarray + updated_padded_object_phase: np.ndarray Updated padded phase object estimate """ @@ -548,6 +548,37 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): return xp.real(current_object) + def _object_anti_gridding_contraint(self, current_object): + """ + Zero outer pixels of object fft to remove gridding artifacts + + Parameters + -------- + current_object: np.ndarray + Current object estimate + + Returns + -------- + constrained_object: np.ndarray + Constrained object estimate + """ + xp = self._xp + + #find indices to zero accounting for object padding + width_x = self._grid_scan_shape[0] + width_y = self._grid_scan_shape[1] + ind_min_x = int(xp.floor(width_x / 2) - 1) + ind_max_x = int(xp.ceil(width_x / 2) + 1) + ind_min_y = int(xp.floor(width_y / 2) - 1) + ind_max_y = int(xp.ceil(width_y / 2) + 1) + + #zero pixels + object_fft = xp.fft.fft2(current_object) + object_fft[ind_min_x:-ind_max_x] = 0 + object_fft[:, ind_min_y:-ind_max_y] = 0 + + return xp.real(xp.fft.ifft2(object_fft)) + def _constraints( self, current_object, @@ -556,6 +587,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + anti_gridding, ): """ DPC constraints operator. @@ -574,6 +606,9 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + anti_gridding: bool + If true, zero outer pixels of object fft to remove + gridding artifacts Returns -------- @@ -592,6 +627,11 @@ def _constraints( q_highpass, ) + if anti_gridding: + current_object = self._object_anti_gridding_contraint( + current_object, + ) + return current_object def reconstruct( @@ -607,6 +647,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + anti_gridding: float = True, store_iterations: bool = False, ): """ @@ -638,6 +679,9 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + anti_gridding: bool + If true, zero outer pixels of object fft to remove + gridding artifacts store_iterations: bool, optional If True, all reconstruction iterations will be stored @@ -667,8 +711,8 @@ def reconstruct( if reset: self.error = np.inf self._step_size = step_size if step_size is not None else 0.5 - self._padded_phase_object = self._padded_phase_object_initial.copy() - + self._padded_object_phase = self._padded_object_phase_initial.copy() + self.error = getattr(self, "error", np.inf) if step_size is None: @@ -676,7 +720,7 @@ def reconstruct( else: self._step_size = step_size - mask = xp.zeros(self._padded_phase_object.shape, dtype="bool") + mask = xp.zeros(self._padded_object_phase.shape, dtype="bool") mask[: self._grid_scan_shape[0], : self._grid_scan_shape[1]] = True mask_inv = xp.logical_not(mask) @@ -689,18 +733,18 @@ def reconstruct( ): if self._step_size < stopping_criterion: break - - previous_iteration = self._padded_phase_object.copy() - + + previous_iteration = self._padded_object_phase.copy() + # forward operator com_dx, com_dy, new_error, self._step_size = self._forward( - self._padded_phase_object, mask, mask_inv, self.error, self._step_size + self._padded_object_phase, mask, mask_inv, self.error, self._step_size ) # if the error went up after the previous step, go back to the step # before the error rose and continue with the halved step size if (new_error > self.error) and backtrack: - self._padded_phase_object = previous_iteration + self._padded_object_phase = previous_iteration self._step_size /= 2 print(f"Iteration {a0}, step reduced to {self._step_size}") continue @@ -710,13 +754,13 @@ def reconstruct( phase_update = self._adjoint(com_dx, com_dy, self._kx_op, self._ky_op) # update - self._padded_phase_object = self._update( - self._padded_phase_object, phase_update, self._step_size + self._padded_object_phase = self._update( + self._padded_object_phase, phase_update, self._step_size ) # constraints - self._padded_phase_object = self._constraints( - self._padded_phase_object, + self._padded_object_phase = self._constraints( + self._padded_object_phase, gaussian_filter=a0 < gaussian_filter_iter and gaussian_filter_sigma is not None, gaussian_filter_sigma=gaussian_filter_sigma, @@ -724,12 +768,13 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + anti_gridding=anti_gridding, ) if store_iterations: self.object_phase_iterations.append( asnumpy( - self._padded_phase_object[ + self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ].copy() ) @@ -743,7 +788,7 @@ def reconstruct( ) # crop result - self._object_phase = self._padded_phase_object[ + self._object_phase = self._padded_object_phase[ : self._grid_scan_shape[0], : self._grid_scan_shape[1] ] self.object_phase = asnumpy(self._object_phase) From 395bb0c305d61b8ffde6c22935393fd0ca17a96e Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 8 Jun 2023 20:02:09 -0700 Subject: [PATCH 209/362] fix for anti gridding --- py4DSTEM/process/phase/iterative_dpc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 949ae0d45..dc29d9c6a 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -564,18 +564,18 @@ def _object_anti_gridding_contraint(self, current_object): """ xp = self._xp - #find indices to zero accounting for object padding - width_x = self._grid_scan_shape[0] - width_y = self._grid_scan_shape[1] - ind_min_x = int(xp.floor(width_x / 2) - 1) - ind_max_x = int(xp.ceil(width_x / 2) + 1) - ind_min_y = int(xp.floor(width_y / 2) - 1) - ind_max_y = int(xp.ceil(width_y / 2) + 1) + #find indices to zero + width_x = current_object.shape[0] + width_y = current_object.shape[1] + ind_min_x = int(xp.floor(width_x / 2) - 2) + ind_max_x = int(xp.ceil(width_x / 2) + 2) + ind_min_y = int(xp.floor(width_y / 2) - 2) + ind_max_y = int(xp.ceil(width_y / 2) + 2) #zero pixels object_fft = xp.fft.fft2(current_object) - object_fft[ind_min_x:-ind_max_x] = 0 - object_fft[:, ind_min_y:-ind_max_y] = 0 + object_fft[ind_min_x:ind_max_x] = 0 + object_fft[:, ind_min_y:ind_max_y] = 0 return xp.real(xp.fft.ifft2(object_fft)) From 6ad9aa7912c57ea5e84603f2b953f9466aa095e5 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 10 Jun 2023 15:46:18 -0700 Subject: [PATCH 210/362] butterworth order --- .../process/phase/iterative_base_class.py | 2 +- py4DSTEM/process/phase/iterative_dpc.py | 22 ++++++++++++++----- .../iterative_multislice_ptychography.py | 2 ++ .../iterative_overlap_magnetic_tomography.py | 22 ++++++++++++++++--- .../phase/iterative_overlap_tomography.py | 22 ++++++++++++++----- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index c383598b2..57049a83e 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -2225,6 +2225,6 @@ def positions(self): @property def _object_cropped(self): - """ cropped and rotated object """ + """cropped and rotated object""" return self._crop_rotate_object_fov(self._object) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index dc29d9c6a..0c5fbb7a9 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -510,7 +510,9 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter used for low/high-pass filtering. @@ -522,6 +524,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- @@ -537,9 +541,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -564,7 +568,7 @@ def _object_anti_gridding_contraint(self, current_object): """ xp = self._xp - #find indices to zero + # find indices to zero width_x = current_object.shape[0] width_y = current_object.shape[1] ind_min_x = int(xp.floor(width_x / 2) - 2) @@ -572,7 +576,7 @@ def _object_anti_gridding_contraint(self, current_object): ind_min_y = int(xp.floor(width_y / 2) - 2) ind_max_y = int(xp.ceil(width_y / 2) + 2) - #zero pixels + # zero pixels object_fft = xp.fft.fft2(current_object) object_fft[ind_min_x:ind_max_x] = 0 object_fft[:, ind_min_y:ind_max_y] = 0 @@ -587,6 +591,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + butterworth_order, anti_gridding, ): """ @@ -606,6 +611,8 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter anti_gridding: bool If true, zero outer pixels of object fft to remove gridding artifacts @@ -625,6 +632,7 @@ def _constraints( current_object, q_lowpass, q_highpass, + butterworth_order, ) if anti_gridding: @@ -647,6 +655,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + butterworth_order: float = 2, anti_gridding: float = True, store_iterations: bool = False, ): @@ -679,6 +688,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter anti_gridding: bool If true, zero outer pixels of object fft to remove gridding artifacts @@ -768,6 +779,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, anti_gridding=anti_gridding, ) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a7fe53589..58f7152c4 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1331,6 +1331,8 @@ def _object_butterworth_constraint( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 2c413c5d2..b74000b14 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1591,7 +1591,9 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter @@ -1603,6 +1605,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- @@ -1618,9 +1622,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -1677,6 +1681,7 @@ def _constraints( q_lowpass_m, q_highpass_e, q_highpass_m, + butterworth_order, object_positivity, shrinkage_rad, object_mask, @@ -1732,6 +1737,8 @@ def _constraints( Cut-off frequency in A^-1 for high-pass filtering electrostatic object q_highpass_m: float Cut-off frequency in A^-1 for high-pass filtering magnetic object + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool If True, forces object to be positive shrinkage_rad: float @@ -1766,21 +1773,25 @@ def _constraints( current_object[0], q_lowpass_e, q_highpass_e, + butterworth_order, ) current_object[1] = self._object_butterworth_constraint( current_object[1], q_lowpass_m, q_highpass_m, + butterworth_order, ) current_object[2] = self._object_butterworth_constraint( current_object[2], q_lowpass_m, q_highpass_m, + butterworth_order, ) current_object[3] = self._object_butterworth_constraint( current_object[3], q_lowpass_m, q_highpass_m, + butterworth_order, ) if shrinkage_rad > 0.0 or object_mask is not None: @@ -1863,6 +1874,7 @@ def reconstruct( q_lowpass_m: float = None, q_highpass_e: float = None, q_highpass_m: float = None, + butterworth_order: float = 2, object_positivity: bool = True, shrinkage_rad: float = 0.0, fix_potential_baseline: bool = True, @@ -1942,6 +1954,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool, optional If True, forces object to be positive shrinkage_rad: float @@ -2408,6 +2422,7 @@ def reconstruct( q_lowpass_m=q_lowpass_m, q_highpass_e=q_highpass_e, q_highpass_m=q_highpass_m, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse @@ -2454,6 +2469,7 @@ def reconstruct( q_lowpass_m=q_lowpass_m, q_highpass_e=q_highpass_e, q_highpass_m=q_highpass_m, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 3337d02cc..c005081b2 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1492,13 +1492,15 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): """ gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object - def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): + def _object_butterworth_constraint( + self, current_object, q_lowpass, q_highpass, butterworth_order + ): """ Butterworth filter @@ -1510,7 +1512,8 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter - + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter Returns -------- constrained_object: np.ndarray @@ -1525,9 +1528,9 @@ def _object_butterworth_constraint(self, current_object, q_lowpass, q_highpass): env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** 4) + env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** 4) + env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -1557,6 +1560,7 @@ def _constraints( butterworth_filter, q_lowpass, q_highpass, + butterworth_order, object_positivity, shrinkage_rad, object_mask, @@ -1605,6 +1609,8 @@ def _constraints( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool If True, forces object to be positive shrinkage_rad: float @@ -1632,6 +1638,7 @@ def _constraints( current_object, q_lowpass, q_highpass, + butterworth_order, ) if shrinkage_rad > 0.0 or object_mask is not None: @@ -1711,6 +1718,7 @@ def reconstruct( butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, + butterworth_order: float = 2, object_positivity: bool = True, shrinkage_rad: float = 0.0, fix_potential_baseline: bool = True, @@ -1788,6 +1796,8 @@ def reconstruct( Cut-off frequency in A^-1 for low-pass butterworth filter q_highpass: float Cut-off frequency in A^-1 for high-pass butterworth filter + butterworth_order: float + Butterworth filter order. Smaller gives a smoother filter object_positivity: bool, optional If True, forces object to be positive shrinkage_rad: float @@ -2172,6 +2182,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse @@ -2213,6 +2224,7 @@ def reconstruct( and (q_lowpass is not None or q_highpass is not None), q_lowpass=q_lowpass, q_highpass=q_highpass, + butterworth_order=butterworth_order, object_positivity=object_positivity, shrinkage_rad=shrinkage_rad, object_mask=self._object_fov_mask_inverse From 95b9c21391b4bca1b33541d6dab873570b3915e8 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 11 Jun 2023 11:29:28 -0700 Subject: [PATCH 211/362] fixing small butterworth order bug --- py4DSTEM/process/phase/iterative_dpc.py | 4 ++-- .../phase/iterative_overlap_magnetic_tomography.py | 10 +++++++--- py4DSTEM/process/phase/iterative_overlap_tomography.py | 10 +++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 0c5fbb7a9..494f661aa 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -541,9 +541,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index b74000b14..0eb7fb924 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1622,9 +1622,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -2439,7 +2439,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index c005081b2..6c773b269 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1528,9 +1528,9 @@ def _object_butterworth_constraint( env = xp.ones_like(qra) if q_highpass: - env *= 1 - 1 / (1 + (qra / q_highpass) ** butterworth_order) + env *= 1 - 1 / (1 + (qra / q_highpass) ** (2 * butterworth_order)) if q_lowpass: - env *= 1 / (1 + (qra / q_lowpass) ** butterworth_order) + env *= 1 / (1 + (qra / q_lowpass) ** (2 * butterworth_order)) current_object_mean = xp.mean(current_object) current_object -= current_object_mean @@ -2197,7 +2197,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, From e1fe3d36316bbf8e202399ec647b0a841d128613 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 11 Jun 2023 14:13:09 -0700 Subject: [PATCH 212/362] nesterov acceleration prefactors for reference. currently unused - see comment on PR #443 --- py4DSTEM/process/phase/utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 5bc44d95a..50d8a792a 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -2,6 +2,7 @@ import matplotlib.pyplot as plt import numpy as np +import functools try: import cupy as cp @@ -1287,3 +1288,16 @@ def project_vector_field_divergence(vector_field, spacings=(1, 1, 1), xp=np): p = preconditioned_poisson_solver(div_v, spacings[0], xp=xp) grad_p = compute_gradient(p, spacings, xp=xp) return vector_field - grad_p + +# Nesterov acceleration functions +# https://blogs.princeton.edu/imabandit/2013/04/01/acceleratedgradientdescent/ + +@functools.cache +def nesterov_lambda(one_indexed_iter_num): + if one_indexed_iter_num == 0: + return 0 + return (1+np.sqrt(1+4*nesterov_lambda(one_indexed_iter_num-1)**2))/2 + +def nesterov_gamma(zero_indexed_iter_num): + one_indexed_iter_num = zero_indexed_iter_num + 1 + return (1-nesterov_lambda(one_indexed_iter_num))/nesterov_lambda(one_indexed_iter_num+1) From 9fb8900d7472902294654c29295dce7183db86aa Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Wed, 14 Jun 2023 08:42:58 -0700 Subject: [PATCH 213/362] step size default update --- py4DSTEM/process/phase/iterative_mixedstate_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 +- py4DSTEM/process/phase/iterative_simultaneous_ptychography.py | 2 +- py4DSTEM/process/phase/iterative_singleslice_ptychography.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index d09b5a339..ff32f5b49 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1226,7 +1226,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 58f7152c4..c0e73e13b 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1623,7 +1623,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 0eb7fb924..67deaaa4f 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1849,7 +1849,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6c773b269..36d32fba7 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1696,7 +1696,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, fix_com: bool = True, diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index c655b82a1..c2a6f047f 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2398,7 +2398,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index cfac995fb..02ad967c9 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1157,7 +1157,7 @@ def reconstruct( reconstruction_parameter: float = 1.0, max_batch_size: int = None, seed_random: int = None, - step_size: float = 0.9, + step_size: float = 0.5, normalization_min: float = 1, positions_step_size: float = 0.9, pure_phase_object_iter: int = 0, From e14a547a35e47daaa67f10a23e48657712dae139 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 14 Jun 2023 09:59:34 -0700 Subject: [PATCH 214/362] changing gaussian sigma normalization --- py4DSTEM/process/phase/iterative_dpc.py | 2 +- .../process/phase/iterative_overlap_magnetic_tomography.py | 2 +- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 +- .../process/phase/iterative_ptychographic_constraints.py | 6 ++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 494f661aa..e6f7659bd 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -505,7 +505,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): xp = self._xp gaussian_filter = self._gaussian_filter - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 67deaaa4f..478e3fe60 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1586,7 +1586,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 36d32fba7..ac98738dc 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1493,7 +1493,7 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): gaussian_filter = self._gaussian_filter xp = self._xp - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) return current_object diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index d0a637204..2abad3d45 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -120,7 +120,7 @@ def _object_gaussian_constraint( """ xp = self._xp gaussian_filter = self._gaussian_filter - gaussian_filter_sigma /= xp.sqrt(self.sampling[0] ** 2 + self.sampling[1] ** 2) + gaussian_filter_sigma /= self.sampling[0] if pure_phase_object: phase = xp.angle(current_object) @@ -518,9 +518,7 @@ def _probe_residual_aberration_filtering_constraint( xp = self._xp gaussian_filter = self._gaussian_filter known_aberrations_array = self._known_aberrations_array - gaussian_filter_sigma /= xp.sqrt( - self._reciprocal_sampling[0] ** 2 + self._reciprocal_sampling[1] ** 2 - ) + gaussian_filter_sigma /= self._reciprocal_sampling[0] fourier_probe = self._return_fourier_probe(current_probe) if fix_amplitude: From 5b1fdb2b7ec7640d46e2fab8707fe333c79d5304 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 14 Jun 2023 10:06:49 -0700 Subject: [PATCH 215/362] small device specification cleanup --- py4DSTEM/process/phase/iterative_parallax.py | 3 ++- py4DSTEM/process/phase/iterative_ptychographic_constraints.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 94f32ad12..5ab4c6cdd 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -79,6 +79,7 @@ def __init__( # Metadata self._energy = energy self._verbose = verbose + self._device = device self._object_padding_px = object_padding_px self._preprocessed = False @@ -725,7 +726,7 @@ def reconstruct( G_ref, G, upsample_factor=upsample_factor, - device="cpu" if xp is np else "gpu", + device=self._device, ) dx = ( diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 2abad3d45..790edaa69 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -333,7 +333,7 @@ def _probe_center_of_mass_constraint(self, current_probe): probe_intensity = xp.abs(current_probe) ** 2 probe_x0, probe_y0 = get_CoM( - probe_intensity, device="cpu" if xp is np else "gpu" + probe_intensity, device=self._device ) shifted_probe = fft_shift( current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp From 3b0c6a459a6094496d466fdb5306f6fa62991529 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 14:45:14 -0700 Subject: [PATCH 216/362] switching to corner-centered probes --- py4DSTEM/process/phase/__init__.py | 28 +-- .../process/phase/iterative_base_class.py | 181 ++++++++---------- .../iterative_ptychographic_constraints.py | 36 ++-- .../iterative_singleslice_ptychography.py | 88 +++++---- py4DSTEM/process/phase/utils.py | 63 +++--- py4DSTEM/process/utils/utils.py | 15 +- 6 files changed, 197 insertions(+), 214 deletions(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index c2e141399..207e44b56 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -1,22 +1,14 @@ +# fmt: off + _emd_hook = True from py4DSTEM.process.phase.iterative_dpc import DPCReconstruction -from py4DSTEM.process.phase.iterative_mixedstate_ptychography import ( - MixedstatePtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_multislice_ptychography import ( - MultislicePtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import ( - OverlapMagneticTomographicReconstruction, -) -from py4DSTEM.process.phase.iterative_overlap_tomography import ( - OverlapTomographicReconstruction, -) +from py4DSTEM.process.phase.iterative_mixedstate_ptychography import MixedstatePtychographicReconstruction +from py4DSTEM.process.phase.iterative_multislice_ptychography import MultislicePtychographicReconstruction +from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import OverlapMagneticTomographicReconstruction +from py4DSTEM.process.phase.iterative_overlap_tomography import OverlapTomographicReconstruction from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction -from py4DSTEM.process.phase.iterative_simultaneous_ptychography import ( - SimultaneousPtychographicReconstruction, -) -from py4DSTEM.process.phase.iterative_singleslice_ptychography import ( - SingleslicePtychographicReconstruction, -) +from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction +from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction + +# fmt: on diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 57049a83e..6bb429a64 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -144,6 +144,13 @@ def _preprocess_datacube_and_vacuum_probe( Resampled and Padded datacube """ + if com_shifts is not None: + if np.isscalar(com_shifts[0]): + com_shifts = ( + np.ones(self._datacube.Rshape) * com_shifts[0], + np.ones(self._datacube.Rshape) * com_shifts[1], + ) + if diffraction_intensities_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = diffraction_intensities_shape @@ -571,7 +578,7 @@ def _solve_for_center_of_mass_relative_rotation( warnings.warn( ( "Best fit rotation forced to " - f"{str(np.round(force_com_rotation))} degrees." + f"{force_com_rotation:.0f} degrees." ), UserWarning, ) @@ -741,12 +748,7 @@ def _solve_for_center_of_mass_relative_rotation( _rotation_best_rad = rotation_angles_rad[ind_min] if self._verbose: - print( - ( - "Best fit rotation = " - f"{str(np.round(rotation_best_deg))} degrees." - ) - ) + print(("Best fit rotation = " f"{rotation_best_deg:.0f} degrees.")) if plot_rotation: figsize = kwargs.get("figsize", (8, 2)) @@ -901,12 +903,7 @@ def _solve_for_center_of_mass_relative_rotation( self._rotation_angles_deg = rotation_angles_deg # Print summary if self._verbose: - print( - ( - "Best fit rotation = " - f"{str(np.round(rotation_best_deg))} degrees." - ) - ) + print(("Best fit rotation = " f"{rotation_best_deg:.0f} degrees.")) if _rotation_best_transpose: print("Diffraction intensities should be transposed.") else: @@ -1373,11 +1370,6 @@ def _set_polar_parameters(self, parameters: dict): ---------- parameters: dict Mapping from aberration symbols to their corresponding values. - - Mutates - ------- - self._polar_parameters: dict - Updated polar aberrations dictionary """ for symbol, value in parameters.items(): @@ -1403,11 +1395,6 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): Input probe positions in Å. If None, a raster scan using experimental parameters is constructed. - Mutates - ------- - self._object_padding_px: np.ndarray - Object array padding in pixels - Returns ------- positions_in_px: (J,2) np.ndarray @@ -1456,74 +1443,17 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): positions -= np.min(positions, axis=0) if self._object_padding_px is None: - self._object_padding_px = self._region_of_interest_shape / 2 - positions += self._object_padding_px + float_padding = self._region_of_interest_shape / 2 + self._object_padding_px = (float_padding, float_padding) + positions[:, 0] += self._object_padding_px[0][0] + positions[:, 1] += self._object_padding_px[1][0] return positions - def _wrapped_indices_2D_window( - self, - center_position: np.ndarray, - window_shape: Sequence[int], - array_shape: Sequence[int], - ): - """ - Computes periodic indices for a window_shape probe centered at center_position, - in object of size array_shape. - - Parameters - ---------- - center_position: (2,) np.ndarray - The window center positions in pixels - window_shape: (2,) Sequence[int] - The pixel dimensions of the window - array_shape: (2,) Sequence[int] - The pixel dimensions of the array the window will be embedded in - - Returns - ------- - window_indices: length-2 tuple of - The 2D indices of the window - """ - - asnumpy = self._asnumpy - sx, sy = array_shape - nx, ny = window_shape - - cx, cy = np.round(asnumpy(center_position)).astype(int) - ox, oy = (cx - nx // 2, cy - ny // 2) - - return np.ix_(np.arange(ox, ox + nx) % sx, np.arange(oy, oy + ny) % sy) - - def _sum_overlapping_patches(self, patches: np.ndarray): - """ - Sum overlapping patches defined into object shaped array - - Parameters - ---------- - patches: (Rx*Ry,Sx,Sy) np.ndarray - Patches to sum - - Returns - ------- - out_array: (Px,Py) np.ndarray - Summed array - """ - xp = self._xp - positions = self._positions_px - patch_shape = self._region_of_interest_shape - array_shape = self._object_shape - - out_array = xp.zeros(array_shape, patches.dtype) - for ind, pos in enumerate(positions): - indices = self._wrapped_indices_2D_window(pos, patch_shape, array_shape) - out_array[indices] += patches[ind] - - return out_array - def _sum_overlapping_patches_bincounts_base(self, patches: np.ndarray): """ Base bincouts overlapping patches sum function, operating on real-valued arrays. + Note this assumes the probe is corner-centered. Parameters ---------- @@ -1540,8 +1470,8 @@ def _sum_overlapping_patches_bincounts_base(self, patches: np.ndarray): y0 = xp.round(self._positions_px[:, 1]).astype("int") roi_shape = self._region_of_interest_shape - x_ind = xp.round(xp.arange(roi_shape[0]) - roi_shape[0] / 2).astype("int") - y_ind = xp.round(xp.arange(roi_shape[1]) - roi_shape[1] / 2).astype("int") + x_ind = xp.fft.fftfreq(roi_shape[0], d=1 / roi_shape[0]).astype("int") + y_ind = xp.fft.fftfreq(roi_shape[1], d=1 / roi_shape[1]).astype("int") flat_weights = patches.ravel() indices = ( @@ -1583,6 +1513,7 @@ def _sum_overlapping_patches_bincounts(self, patches: np.ndarray): def _extract_vectorized_patch_indices(self): """ Sets the vectorized row/col indices used for the overlap projection + Note this assumes the probe is corner-centered. Returns ------- @@ -1596,8 +1527,8 @@ def _extract_vectorized_patch_indices(self): y0 = xp.round(self._positions_px[:, 1]).astype("int") roi_shape = self._region_of_interest_shape - x_ind = xp.round(xp.arange(roi_shape[0]) - roi_shape[0] / 2).astype("int") - y_ind = xp.round(xp.arange(roi_shape[1]) - roi_shape[1] / 2).astype("int") + x_ind = xp.fft.fftfreq(roi_shape[0], d=1 / roi_shape[0]).astype("int") + y_ind = xp.fft.fftfreq(roi_shape[1], d=1 / roi_shape[1]).astype("int") obj_shape = self._object_shape vectorized_patch_indices_row = ( @@ -1769,8 +1700,7 @@ def tune_angle_and_defocus( fig = plt.figure(figsize=figsize) - progress_bar = kwargs.get("progress_bar", False) - kwargs.pop("progress_bar", None) + progress_bar = kwargs.pop("progress_bar", False) # run loop and plot along the way self._verbose = False for flat_index, (angle, defocus) in enumerate( @@ -2038,7 +1968,7 @@ def _return_fourier_probe( ): """ Returns complex fourier probe shifted to center of array from - complex real space probe in center + corner-centered complex real space probe Parameters ---------- @@ -2057,16 +1987,61 @@ def _return_fourier_probe( else: probe = xp.asarray(probe, dtype=xp.complex64) - return xp.fft.fftshift( - xp.fft.fft2(xp.fft.ifftshift(probe, axes=(-2, -1))), axes=(-2, -1) - ) + return xp.fft.fftshift(xp.fft.fft2(probe), axes=(-2, -1)) + + def _return_fourier_probe_from_centered_probe( + self, + probe=None, + ): + """ + Returns complex fourier probe shifted to center of array from + centered complex real space probe + + Parameters + ---------- + probe: complex array, optional + if None is specified, uses self._probe + + Returns + ------- + fourier_probe: np.ndarray + Fourier-transformed and center-shifted probe. + """ + xp = self._xp + return self._return_fourier_probe(xp.fft.ifftshift(probe, axes=(-2, -1))) + + def _return_centered_probe( + self, + probe=None, + ): + """ + Returns complex probe centered in middle of the array. + + Parameters + ---------- + probe: complex array, optional + if None is specified, uses self._probe + + Returns + ------- + centered_probe: np.ndarray + Center-shifted probe. + """ + xp = self._xp + + if probe is None: + probe = self._probe + else: + probe = xp.asarray(probe, dtype=xp.complex64) + + return xp.fft.fftshift(probe, axes=(-2, -1)) def _return_object_fft( self, obj=None, ): """ - Returns obj fft shifted to center of array + Returns absolute value of obj fft shifted to center of array Parameters ---------- @@ -2084,7 +2059,7 @@ def _return_object_fft( obj = self._object obj = self._crop_rotate_object_fov(asnumpy(obj)) - return np.abs(np.fft.fftshift(np.fft.fft2(obj))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) def show_fourier_probe( self, @@ -2175,13 +2150,21 @@ def show_object_fft(self, obj=None, **kwargs): @property def probe_fourier(self): """Current probe estimate in Fourier space""" - if not hasattr(self, "_probe"): return None asnumpy = self._asnumpy return asnumpy(self._return_fourier_probe(self._probe)) + @property + def probe_centered(self): + """Current probe estimate shifted to the center""" + if not hasattr(self, "_probe"): + return None + + asnumpy = self._asnumpy + return asnumpy(self._return_centered_probe(self._probe)) + @property def object_fft(self): """Fourier transform of current object estimate""" @@ -2224,7 +2207,7 @@ def positions(self): return asnumpy(positions) @property - def _object_cropped(self): + def object_cropped(self): """cropped and rotated object""" return self._crop_rotate_object_fov(self._object) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 790edaa69..10b24eb78 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -315,7 +315,7 @@ def _object_denoise_tv_chambolle( def _probe_center_of_mass_constraint(self, current_probe): """ Ptychographic center of mass constraint. - Used for centering probe intensity. + Used for centering corner-centered probe intensity. Parameters -------- @@ -329,15 +329,12 @@ def _probe_center_of_mass_constraint(self, current_probe): """ xp = self._xp - probe_center = xp.array(self._region_of_interest_shape) / 2 probe_intensity = xp.abs(current_probe) ** 2 probe_x0, probe_y0 = get_CoM( - probe_intensity, device=self._device - ) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp + probe_intensity, device=self._device, corner_centered=True ) + shifted_probe = fft_shift(current_probe, -xp.array([probe_x0, probe_y0]), xp) return shifted_probe @@ -352,13 +349,14 @@ def _probe_radial_symmetrization_constraint_base( sx, sy = current_probe.shape if center is None: - center = (sx // 2, sy // 2) + center = (0, 0) if num_bins is None: num_bins = np.maximum(sx, sy) * 2 + 1 cx, cy = center - X, Y = xp.ogrid[0:sx, 0:sy] + X = xp.fft.fftfreq(sx, d=1 / sx)[:, None] + Y = xp.fft.fftfreq(sy, d=1 / sy)[None] r = xp.hypot(X - cx, Y - cy) rbin = (num_bins * r / r.max()).astype("int") @@ -383,7 +381,7 @@ def _probe_radial_symmetrization_constraint( xp = self._xp current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) - fourier_probe = self._return_fourier_probe(current_probe) + fourier_probe = xp.fft.fft2(current_probe) fourier_probe_real = fourier_probe.real.copy() fourier_probe_imag = fourier_probe.imag.copy() @@ -396,7 +394,7 @@ def _probe_radial_symmetrization_constraint( ) fourier_probe = fourier_probe_real + 1.0j * fourier_probe_imag - current_probe = xp.fft.ifftshift(xp.fft.ifft2(xp.fft.fftshift(fourier_probe))) + current_probe = xp.fft.ifft2(fourier_probe) current_probe *= xp.sqrt(current_probe_sum / np.sum(np.abs(current_probe) ** 2)) return current_probe @@ -427,13 +425,12 @@ def _probe_amplitude_constraint( probe_intensity = xp.abs(current_probe) ** 2 current_probe_sum = xp.sum(probe_intensity) - x = xp.linspace(-1 / 2, 1 / 2, current_probe.shape[0]) - y = xp.linspace(-1 / 2, 1 / 2, current_probe.shape[1]) - xa, ya = xp.meshgrid(x, y, indexing="ij") - ra = xp.sqrt(xa**2 + ya**2) - relative_radius + X = xp.fft.fftfreq(current_probe.shape[0])[:, None] + Y = xp.fft.fftfreq(current_probe.shape[1])[None] + r = xp.hypot(X, Y) - relative_radius sigma = np.sqrt(np.pi) / relative_width - tophat_mask = 0.5 * (1 - erf(sigma * ra / (1 - ra**2))) + tophat_mask = 0.5 * (1 - erf(sigma * r / (1 - r**2))) updated_probe = current_probe * tophat_mask updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) @@ -483,7 +480,6 @@ def _probe_fourier_amplitude_constraint( sigma = np.sqrt(np.pi) / relative_width tophat_mask = 0.5 * (1 - erf(sigma * qra / (1 - qra**2))) - updated_probe = xp.fft.ifft2(current_probe_fft * tophat_mask) updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) normalization = xp.sqrt(current_probe_sum / updated_probe_sum) @@ -520,19 +516,21 @@ def _probe_residual_aberration_filtering_constraint( known_aberrations_array = self._known_aberrations_array gaussian_filter_sigma /= self._reciprocal_sampling[0] - fourier_probe = self._return_fourier_probe(current_probe) + fourier_probe = xp.fft.fft2(current_probe) if fix_amplitude: fourier_probe_abs = xp.abs(fourier_probe) fourier_probe *= xp.conjugate(known_aberrations_array) - fourier_probe = gaussian_filter(fourier_probe, gaussian_filter_sigma) + fourier_probe = gaussian_filter( + fourier_probe, gaussian_filter_sigma, mode="wrap" + ) fourier_probe *= known_aberrations_array if fix_amplitude: fourier_probe_angle = xp.angle(fourier_probe) fourier_probe = fourier_probe_abs * xp.exp(1.0j * fourier_probe_angle) - current_probe = xp.fft.ifftshift(xp.fft.ifft2(xp.fft.fftshift(fourier_probe))) + current_probe = xp.fft.ifft2(fourier_probe) return current_probe diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 02ad967c9..5ef8985c6 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -346,16 +346,16 @@ def preprocess( self._positions_px = self._calculate_scan_positions_in_pixels( self._scan_positions ) - # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((p, q), dtype=xp.float32) @@ -398,18 +398,16 @@ def preprocess( self._vacuum_probe_intensity, dtype=xp.float32 ) probe_x0, probe_y0 = get_CoM( - self._vacuum_probe_intensity, device=self._device + self._vacuum_probe_intensity, + device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) - self._probe = ( ComplexProbe( gpts=self._region_of_interest_shape, @@ -457,8 +455,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe, self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -481,7 +477,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -1597,11 +1593,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -1715,12 +1711,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -1786,19 +1790,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -1942,12 +1948,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2003,16 +2017,25 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") + else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2020,9 +2043,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 50d8a792a..6a14bc508 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -15,46 +15,26 @@ from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from scipy.ndimage import gaussian_filter +# fmt: off + #: Symbols for the polar representation of all optical aberrations up to the fifth order. polar_symbols = ( - "C10", - "C12", - "phi12", - "C21", - "phi21", - "C23", - "phi23", - "C30", - "C32", - "phi32", - "C34", - "phi34", - "C41", - "phi41", - "C43", - "phi43", - "C45", - "phi45", - "C50", - "C52", - "phi52", - "C54", - "phi54", - "C56", - "phi56", + "C10", "C12", "phi12", + "C21", "phi21", "C23", "phi23", + "C30", "C32", "phi32", "C34", "phi34", + "C41", "phi41", "C43", "phi43", "C45", "phi45", + "C50", "C52", "phi52", "C54", "phi54", "C56", "phi56", ) #: Aliases for the most commonly used optical aberrations. polar_aliases = { - "defocus": "C10", - "astigmatism": "C12", - "astigmatism_angle": "phi12", - "coma": "C21", - "coma_angle": "phi21", - "Cs": "C30", - "C5": "C50", + "defocus": "C10", "astigmatism": "C12", "astigmatism_angle": "phi12", + "coma": "C21", "coma_angle": "phi21", + "Cs": "C30", + "C5": "C50", } +# fmt: on ### Probe functions @@ -81,6 +61,8 @@ class ComplexProbe: Device to perform calculations on. Must be either 'cpu' or 'gpu' rolloff: float, optional Tapers the cutoff edge over the given angular range [mrad]. + vacuum_probe_intensity: np.ndarray, optional + Squared of corner-centered aperture amplitude to use, instead of semiangle_cutoff + rolloff focal_spread: float, optional The 1/e width of the focal spread due to chromatic aberration and lens current instability [Å]. angular_spread: float, optional @@ -180,7 +162,7 @@ def evaluate_aperture( self._vacuum_probe_intensity, dtype=xp.float32 ) vacuum_probe_amplitude = xp.sqrt(xp.maximum(vacuum_probe_intensity, 0)) - return xp.fft.ifftshift(vacuum_probe_amplitude) + return vacuum_probe_amplitude if self._semiangle_cutoff == xp.inf: return xp.ones_like(alpha) @@ -432,9 +414,9 @@ def polar_coordinates(self, x, y): return alpha, phi def build(self): - """Builds complex probe in the center of the region of interest.""" + """Builds corner-centered complex probe in the center of the region of interest.""" xp = self._xp - array = xp.fft.fftshift(xp.fft.ifft2(self._evaluate_ctf())) + array = xp.fft.ifft2(self._evaluate_ctf()) array = array / xp.sqrt((xp.abs(array) ** 2).sum()) self._array = array return self @@ -448,7 +430,7 @@ def visualize(self, **kwargs): kwargs.pop("cmap", None) plt.imshow( - asnumpy(xp.abs(self._array) ** 2), + asnumpy(xp.abs(xp.fft.ifftshift(self._array)) ** 2), cmap=cmap, **kwargs, ) @@ -1289,15 +1271,20 @@ def project_vector_field_divergence(vector_field, spacings=(1, 1, 1), xp=np): grad_p = compute_gradient(p, spacings, xp=xp) return vector_field - grad_p + # Nesterov acceleration functions # https://blogs.princeton.edu/imabandit/2013/04/01/acceleratedgradientdescent/ + @functools.cache def nesterov_lambda(one_indexed_iter_num): if one_indexed_iter_num == 0: return 0 - return (1+np.sqrt(1+4*nesterov_lambda(one_indexed_iter_num-1)**2))/2 + return (1 + np.sqrt(1 + 4 * nesterov_lambda(one_indexed_iter_num - 1) ** 2)) / 2 + def nesterov_gamma(zero_indexed_iter_num): one_indexed_iter_num = zero_indexed_iter_num + 1 - return (1-nesterov_lambda(one_indexed_iter_num))/nesterov_lambda(one_indexed_iter_num+1) + return (1 - nesterov_lambda(one_indexed_iter_num)) / nesterov_lambda( + one_indexed_iter_num + 1 + ) diff --git a/py4DSTEM/process/utils/utils.py b/py4DSTEM/process/utils/utils.py index 29badd389..1df4e78c5 100644 --- a/py4DSTEM/process/utils/utils.py +++ b/py4DSTEM/process/utils/utils.py @@ -174,21 +174,24 @@ def make_Fourier_coords2D(Nx, Ny, pixelSize=1): qy, qx = np.meshgrid(qy, qx) return qx, qy - -def get_CoM(ar, device = "cpu"): +def get_CoM(ar, device="cpu", corner_centered=False): """ Finds and returns the center of mass of array ar. + If corner_centered is True, uses fftfreq for indices. """ if device == "cpu": xp = np - elif device == "gpu": xp = cp - ar = xp.asarray(ar) - + ar = xp.asarray(ar) nx, ny = ar.shape - ry, rx = xp.meshgrid(xp.arange(ny), xp.arange(nx)) + + if corner_centered: + ry, rx = xp.meshgrid(xp.fft.fftfreq(ny, 1 / ny), xp.fft.fftfreq(nx, 1 / nx)) + else: + ry, rx = xp.meshgrid(xp.arange(ny), xp.arange(nx)) + tot_intens = xp.sum(ar) xCoM = xp.sum(rx * ar) / tot_intens yCoM = xp.sum(ry * ar) / tot_intens From e5bb0ced76ba00511f38715e19a77a502c693bb4 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 09:25:04 -0700 Subject: [PATCH 217/362] handing of single value for com shifts --- py4DSTEM/process/phase/iterative_base_class.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 6bb429a64..def3f8799 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -143,6 +143,12 @@ def _preprocess_datacube_and_vacuum_probe( datacube: Datacube Resampled and Padded datacube """ + if com_shifts is not None: + if np.isscalar(com_shifts[0]): + com_shifts = ( + np.ones(self._datacube.Rshape) * com_shifts[0], + np.ones(self._datacube.Rshape) * com_shifts[1], + ) if com_shifts is not None: if np.isscalar(com_shifts[0]): From 196d9971d3d81d6f60b5218397d3a3ed7faeeaa7 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 14:46:17 -0700 Subject: [PATCH 218/362] removing merge conflict duplicate lines --- py4DSTEM/process/phase/iterative_base_class.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index def3f8799..288c573cd 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -150,13 +150,6 @@ def _preprocess_datacube_and_vacuum_probe( np.ones(self._datacube.Rshape) * com_shifts[1], ) - if com_shifts is not None: - if np.isscalar(com_shifts[0]): - com_shifts = ( - np.ones(self._datacube.Rshape) * com_shifts[0], - np.ones(self._datacube.Rshape) * com_shifts[1], - ) - if diffraction_intensities_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = diffraction_intensities_shape From 9fa6d0af5133bab24be74949610e4e6d017740d5 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 15:21:29 -0700 Subject: [PATCH 219/362] corner-centered probe multislice --- .../iterative_multislice_ptychography.py | 95 ++++++++++++------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index c0e73e13b..ce8d13325 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -421,13 +421,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((self._num_slices, p, q), dtype=xp.float32) @@ -470,14 +471,13 @@ def preprocess( self._vacuum_probe_intensity, dtype=xp.float32 ) probe_x0, probe_y0 = get_CoM( - self._vacuum_probe_intensity, device=self._device + self._vacuum_probe_intensity, + device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -530,8 +530,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._propagator_arrays = self._precompute_propagator_arrays( self._region_of_interest_shape, @@ -562,7 +560,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -577,7 +575,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2090,11 +2088,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -2215,12 +2213,21 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2287,19 +2294,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2445,12 +2454,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2505,16 +2522,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2522,9 +2547,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert @@ -2621,6 +2643,7 @@ def show_transmitted_probe( """ xp = self._xp + asnumpy = self._asnumpy transmitted_probe_intensities = xp.sum( xp.abs(self._transmitted_probes) ** 2, axis=(-2, -1) @@ -2633,7 +2656,7 @@ def show_transmitted_probe( ] mean_transmitted = self._transmitted_probes.mean(0) probes = [ - self._asnumpy(probe) + asnumpy(self._return_centered_probe(probe)) for probe in [ mean_transmitted, min_intensity_transmitted, @@ -2648,7 +2671,7 @@ def show_transmitted_probe( if plot_fourier_probe: bottom_row = [ - self._asnumpy(self._return_fourier_probe(probe)) + asnumpy(self._return_fourier_probe(probe)) for probe in [ mean_transmitted, min_intensity_transmitted, @@ -2988,4 +3011,4 @@ def _return_object_fft( obj = np.angle(obj) obj = self._crop_rotate_object_fov(np.sum(obj, axis=0)) - return np.abs(np.fft.fftshift(np.fft.fft2(obj))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) From 3b6fdc709e38857f1a7909832bdb38de14fb9106 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 16:22:27 -0700 Subject: [PATCH 220/362] corner-centered probe mixedstate --- .../iterative_mixedstate_ptychography.py | 112 ++++++++++-------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index ff32f5b49..2d595fab1 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -347,13 +347,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": self._object = xp.zeros((p, q), dtype=xp.float32) @@ -400,12 +401,10 @@ def preprocess( self._vacuum_probe_intensity, device=self._device, ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -476,8 +475,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe[0], self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -500,7 +497,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe[0]), + self.probe_centered[0], vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -536,7 +533,7 @@ def preprocess( ) ax1.set_ylabel("x [A]") ax1.set_xlabel("y [A]") - ax1.set_title("Initial Probe") + ax1.set_title("Initial Probe[0]") ax2.imshow( asnumpy(probe_overlap), @@ -1021,8 +1018,8 @@ def _adjoint( def _probe_center_of_mass_constraint(self, current_probe): """ - Ptychographic threshold constraint. - Used for avoiding the scaling ambiguity between probe and object. + Ptychographic center of mass constraint. + Used for centering corner-centered probe intensity. Parameters -------- @@ -1035,15 +1032,12 @@ def _probe_center_of_mass_constraint(self, current_probe): Constrained probe estimate """ xp = self._xp - asnumpy = self._asnumpy - - probe_center = xp.array(self._region_of_interest_shape) / 2 - probe_intensity = asnumpy(xp.abs(current_probe[0]) ** 2) + probe_intensity = xp.abs(current_probe[0]) ** 2 - probe_x0, probe_y0 = get_CoM(probe_intensity) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp + probe_x0, probe_y0 = get_CoM( + probe_intensity, device=self._device, corner_centered=True ) + shifted_probe = fft_shift(current_probe, -xp.array([probe_x0, probe_y0]), xp) return shifted_probe @@ -1063,10 +1057,9 @@ def _probe_orthogonalization_constraint(self, current_probe): Orthogonalized probe estimate """ xp = self._xp + shape = current_probe.shape - return orthogonalize(current_probe.reshape((self._num_probes, -1)), xp).reshape( - current_probe.shape - ) + return orthogonalize(current_probe.reshape((shape[0], -1)), xp).reshape(shape) def _constraints( self, @@ -1663,11 +1656,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -1779,12 +1772,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -1849,20 +1850,22 @@ def _visualize_last_iteration( probe_array = Complex2RGB( self.probe_fourier[0], hue_start=hue_start, invert=invert ) - ax.set_title("Reconstructed Fourier probe") + ax.set_title("Reconstructed Fourier probe[0]") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe[0], hue_start=hue_start, invert=invert ) - ax.set_title("Reconstructed probe") + ax.set_title("Reconstructed probe[0]") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2006,12 +2009,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2066,16 +2077,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]][0])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]][0] + ) + ), hue_start=hue_start, invert=invert, ) - ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_title(f"Iter: {grid_range[n]} Fourier probe[0]") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]][0], hue_start=hue_start, invert=invert ) - ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_title(f"Iter: {grid_range[n]} probe[0]") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2083,9 +2102,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert From 44ee041a839f33cac73a903fa9a53f1dd960a6e5 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 16:41:35 -0700 Subject: [PATCH 221/362] corner-centered probe simultaneous --- .../iterative_simultaneous_ptychography.py | 77 +++++++------------ 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index c2a6f047f..e872bc42e 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -593,13 +593,14 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( - int + "int" ) q = np.max([np.round(q + pad_y), self._region_of_interest_shape[1]]).astype( - int + "int" ) if self._object_type == "potential": object_e = xp.zeros((p, q), dtype=xp.float32) @@ -647,12 +648,10 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -704,8 +703,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # overlaps shifted_probes = fft_shift(self._probe, self._positions_px_fractional, xp) probe_intensities = xp.abs(shifted_probes) ** 2 @@ -728,7 +725,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2173,34 +2170,6 @@ def _adjoint( return current_object, current_probe - def _probe_center_of_mass_constraint(self, current_probe): - """ - Ptychographic threshold constraint. - Used for avoiding the scaling ambiguity between probe and object. - - Parameters - -------- - current_probe: np.ndarray - Current probe estimate - - Returns - -------- - constrained_probe: np.ndarray - Constrained probe estimate - """ - xp = self._xp - asnumpy = self._asnumpy - - probe_center = xp.array(self._region_of_interest_shape) / 2 - probe_intensity = asnumpy(xp.abs(current_probe) ** 2) - - probe_x0, probe_y0 = get_CoM(probe_intensity) - shifted_probe = fft_shift( - current_probe, probe_center - xp.array([probe_x0, probe_y0]), xp - ) - - return shifted_probe - def _constraints( self, current_object, @@ -2885,14 +2854,14 @@ def reconstruct( asnumpy(self._object[1].copy()), ) ) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result if a0 < warmup_iter: self.object = (asnumpy(self._object[0]), None) else: self.object = (asnumpy(self._object[0]), asnumpy(self._object[1])) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -3019,12 +2988,20 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -3111,19 +3088,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) From 5e54e9b519ce0d8362dedf086789bb9df82b98ec Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:02:43 -0700 Subject: [PATCH 222/362] corner-centered probe overlap tomography --- .../iterative_overlap_magnetic_tomography.py | 23 ++-- .../phase/iterative_overlap_tomography.py | 115 ++++++++---------- 2 files changed, 62 insertions(+), 76 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 478e3fe60..67d5f2bd5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -602,8 +602,9 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px_all, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px_all, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( "int" ) @@ -654,12 +655,10 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -717,8 +716,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._slice_thicknesses = np.tile( self._object_shape[1] * self.sampling[1] / self._num_slices, @@ -795,7 +792,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -810,7 +807,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2485,11 +2482,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -3030,7 +3027,7 @@ def _return_object_fft( rotated_3d_obj.sum(0), angle=None, x_lims=x_lims, y_lims=y_lims ) - return np.abs(np.fft.fftshift(np.fft.fft2(rotated_object))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(rotated_object)))) def show_object_fft( self, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index ac98738dc..dd5eb2be8 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -254,40 +254,6 @@ def _propagate_array(self, array: np.ndarray, propagator_array: np.ndarray): return xp.fft.ifft2(xp.fft.fft2(array) * propagator_array) - def _expand_or_project_sliced_object(self, array: np.ndarray, output_z): - """ - OLD Version - - Expands supersliced object or projects voxel-sliced object. - - Parameters - ---------- - array: np.ndarray - 3D array to expand/project - output_z: int - Output_dimension to expand/project array to. - If output_z > array.shape[0] array is expanded, else it's projected - - Returns - ------- - expanded_or_projected_array: np.ndarray - expanded or projected array - """ - zoom = self._zoom - input_z = array.shape[0] - - return ( - zoom( - array, - (output_z / input_z, 1, 1), - order=0, - mode="nearest", - grid_mode=True, - ) - * input_z - / output_z - ) - def _project_sliced_object(self, array: np.ndarray, output_z): """ Expands supersliced object or projects voxel-sliced object. @@ -545,8 +511,9 @@ def preprocess( # Object Initialization if self._object is None: - pad_x, pad_y = self._object_padding_px - p, q = np.max(self._positions_px_all, axis=0) + pad_x = self._object_padding_px[0][1] + pad_y = self._object_padding_px[1][1] + p, q = np.round(np.max(self._positions_px_all, axis=0)) p = np.max([np.round(p + pad_x), self._region_of_interest_shape[0]]).astype( "int" ) @@ -601,8 +568,8 @@ def preprocess( shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, - shift_x, - shift_y, + -probe_x0, + -probe_y0, bilinear=True, device=self._device, ) @@ -660,8 +627,6 @@ def preprocess( device=self._device, )._evaluate_ctf() - self._known_aberrations_array = xp.fft.ifftshift(self._known_aberrations_array) - # Precomputed propagator arrays self._slice_thicknesses = np.tile( self._object_shape[1] * self.sampling[1] / self._num_slices, @@ -741,7 +706,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - asnumpy(self._probe), + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -756,7 +721,7 @@ def preprocess( propagated_probe, self._propagator_arrays[s] ) complex_propagated_rgb = Complex2RGB( - asnumpy(propagated_probe), + asnumpy(self._return_centered_probe(propagated_probe)), vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -2240,11 +2205,11 @@ def reconstruct( self.error_iterations.append(error.item()) if store_iterations: self.object_iterations.append(asnumpy(self._object.copy())) - self.probe_iterations.append(asnumpy(self._probe.copy())) + self.probe_iterations.append(self.probe_centered) # store result self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self.error = error.item() return self @@ -2440,12 +2405,21 @@ def _visualize_last_iteration( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2509,19 +2483,21 @@ def _visualize_last_iteration( self.probe_fourier, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( self.probe, hue_start=hue_start, invert=invert ) ax.set_title("Reconstructed probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, extent=probe_extent, **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") if cbar: divider = make_axes_locatable(ax) @@ -2686,12 +2662,20 @@ def _visualize_all_iterations( 0, ] - probe_extent = [ - 0, - self.sampling[1] * self._region_of_interest_shape[1], - self.sampling[0] * self._region_of_interest_shape[0], - 0, - ] + if plot_fourier_probe: + probe_extent = [ + 0, + self.angular_sampling[1] * self._region_of_interest_shape[1], + self.angular_sampling[0] * self._region_of_interest_shape[0], + 0, + ] + elif plot_probe: + probe_extent = [ + 0, + self.sampling[1] * self._region_of_interest_shape[1], + self.sampling[0] * self._region_of_interest_shape[0], + 0, + ] if plot_convergence: if plot_probe or plot_fourier_probe: @@ -2745,16 +2729,24 @@ def _visualize_all_iterations( for n, ax in enumerate(grid): if plot_fourier_probe: probe_array = Complex2RGB( - asnumpy(self._return_fourier_probe(probes[grid_range[n]])), + asnumpy( + self._return_fourier_probe_from_centered_probe( + probes[grid_range[n]] + ) + ), hue_start=hue_start, invert=invert, ) ax.set_title(f"Iter: {grid_range[n]} Fourier probe") + ax.set_ylabel("kx [mrad]") + ax.set_xlabel("ky [mrad]") else: probe_array = Complex2RGB( probes[grid_range[n]], hue_start=hue_start, invert=invert ) ax.set_title(f"Iter: {grid_range[n]} probe") + ax.set_ylabel("x [A]") + ax.set_xlabel("y [A]") im = ax.imshow( probe_array, @@ -2762,9 +2754,6 @@ def _visualize_all_iterations( **kwargs, ) - ax.set_ylabel("x [A]") - ax.set_xlabel("y [A]") - if cbar: add_colorbar_arg( grid.cbar_axes[n], hue_start=hue_start, invert=invert @@ -2909,7 +2898,7 @@ def _return_object_fft( rotated_3d_obj.sum(0), angle=None, x_lims=x_lims, y_lims=y_lims ) - return np.abs(np.fft.fftshift(np.fft.fft2(rotated_object))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(rotated_object)))) def show_object_fft( self, From 38d3bcec3db03dc5b4b2119617445b378dd9699b Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:05:55 -0700 Subject: [PATCH 223/362] some flake8 gotchas --- py4DSTEM/process/phase/iterative_base_class.py | 1 - .../process/phase/iterative_overlap_magnetic_tomography.py | 1 - py4DSTEM/process/phase/iterative_overlap_tomography.py | 3 --- 3 files changed, 5 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 288c573cd..3e55b6d5a 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -3,7 +3,6 @@ """ import warnings -from typing import Sequence import matplotlib.pyplot as plt import numpy as np diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 67d5f2bd5..0ef7725a1 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1581,7 +1581,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): Constrained object estimate """ gaussian_filter = self._gaussian_filter - xp = self._xp gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index dd5eb2be8..4a64f17af 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -564,8 +564,6 @@ def preprocess( probe_x0, probe_y0 = get_CoM( self._vacuum_probe_intensity, device=self._device ) - shift_x = self._region_of_interest_shape[0] // 2 - probe_x0 - shift_y = self._region_of_interest_shape[1] // 2 - probe_y0 self._vacuum_probe_intensity = get_shifted_ar( self._vacuum_probe_intensity, -probe_x0, @@ -1456,7 +1454,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): Constrained object estimate """ gaussian_filter = self._gaussian_filter - xp = self._xp gaussian_filter_sigma /= self.sampling[0] current_object = gaussian_filter(current_object, gaussian_filter_sigma) From 0abdc555855a9a7093e6afd23e8a44abfc347538 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:09:41 -0700 Subject: [PATCH 224/362] supporting old padding format --- py4DSTEM/process/phase/iterative_base_class.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 3e55b6d5a..2ad0a0927 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -1443,6 +1443,12 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): if self._object_padding_px is None: float_padding = self._region_of_interest_shape / 2 self._object_padding_px = (float_padding, float_padding) + elif np.isscalar(self._object_padding_px[0]): + self._object_padding_px = ( + (self._object_padding_px[0],)*2, + (self._object_padding_px[1],)*2 + ) + positions[:, 0] += self._object_padding_px[0][0] positions[:, 1] += self._object_padding_px[1][0] From 4a1c13925e8044c7f340cd588b2ff8f4f76bf7fd Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Fri, 16 Jun 2023 17:25:37 -0700 Subject: [PATCH 225/362] adding show_complex to top-level imports --- py4DSTEM/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/__init__.py b/py4DSTEM/__init__.py index 21409c101..dc8306990 100644 --- a/py4DSTEM/__init__.py +++ b/py4DSTEM/__init__.py @@ -46,7 +46,7 @@ ### visualization from py4DSTEM import visualize -from py4DSTEM.visualize import show +from py4DSTEM.visualize import show,show_complex From 97d6103d3ff8954bd3cf0e8d90c4b83e0465b337 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 09:10:07 -0700 Subject: [PATCH 226/362] switched to svd-like orthogonalization (minor differences) --- .../iterative_mixedstate_ptychography.py | 22 ++++++++++++++++--- py4DSTEM/process/phase/utils.py | 14 ------------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 2d595fab1..067f2aa8a 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -24,7 +24,6 @@ ComplexProbe, fft_shift, generate_batches, - orthogonalize, polar_aliases, polar_symbols, ) @@ -1045,6 +1044,7 @@ def _probe_orthogonalization_constraint(self, current_probe): """ Ptychographic probe-orthogonalization constraint. Used to ensure mixed states are orthogonal to each other. + Adapted from https://github.com/AdvancedPhotonSource/tike/blob/main/src/tike/ptycho/probe.py#L690 Parameters -------- @@ -1057,9 +1057,25 @@ def _probe_orthogonalization_constraint(self, current_probe): Orthogonalized probe estimate """ xp = self._xp - shape = current_probe.shape + n_probes = self._num_probes - return orthogonalize(current_probe.reshape((shape[0], -1)), xp).reshape(shape) + # compute upper half of P* @ P + pairwise_dot_product = xp.empty((n_probes, n_probes), dtype=current_probe.dtype) + + for i in range(n_probes): + for j in range(i, n_probes): + pairwise_dot_product[i, j] = xp.sum( + current_probe[i].conj() * current_probe[j] + ) + + # compute eigenvectors (effectively cheaper way of computing V* from SVD) + _, evecs = xp.linalg.eigh(pairwise_dot_product, UPLO="U") + current_probe = xp.tensordot(evecs.T, current_probe, axes=1) + + # sort by real-space intensity + intensities = xp.sum(xp.abs(current_probe) ** 2, axis=(-2, -1)) + intensities_order = xp.argsort(intensities, axis=None)[::-1] + return current_probe[intensities_order] def _constraints( self, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 6a14bc508..d57ad820a 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -458,20 +458,6 @@ def spatial_frequencies(gpts: Tuple[int, int], sampling: Tuple[float, float]): ) -def projection(u: np.ndarray, v: np.ndarray, xp): - """Projection of vector u onto vector v.""" - return u * xp.vdot(u, v) / xp.vdot(u, u) - - -def orthogonalize(V: np.ndarray, xp): - """Non-normalized QR decomposition using repeated projections.""" - U = V.copy() - for i in range(1, V.shape[0]): - for j in range(i): - U[i, :] -= projection(U[j, :], V[i, :], xp) - return U - - ### FFT-shift functions From e419d67c109c2c79b672ec20c3a65b7e2660e520 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 09:10:41 -0700 Subject: [PATCH 227/362] fixed mixed-state probe initialization bug, expanded preprocess viz to help debug --- .../iterative_mixedstate_ptychography.py | 59 +++++++++---------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 067f2aa8a..4b2187a15 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -442,16 +442,10 @@ def preprocess( # Randomly shift phase of other probes for i_probe in range(1, self._num_probes): shift_x = xp.exp( - -2j - * np.pi - * (xp.random.rand() - 0.5) - * ((xp.arange(sx) + 0.5) / sx - 0.5) + -2j * np.pi * (xp.random.rand() - 0.5) * xp.fft.fftfreq(sx) ) shift_y = xp.exp( - -2j - * np.pi - * (xp.random.rand() - 0.5) - * ((xp.arange(sy) + 0.5) / sy - 0.5) + -2j * np.pi * (xp.random.rand() - 0.5) * xp.fft.fftfreq(sy) ) self._probe[i_probe] = ( self._probe[i_probe - 1] * shift_x[:, None] * shift_y[None] @@ -487,7 +481,7 @@ def preprocess( self._object_fov_mask_inverse = np.invert(self._object_fov_mask) if plot_probe_overlaps: - figsize = kwargs.pop("figsize", (9, 4)) + figsize = kwargs.pop("figsize", (4.5 * self._num_probes + 4, 4)) cmap = kwargs.pop("cmap", "Greys_r") vmin = kwargs.pop("vmin", None) vmax = kwargs.pop("vmax", None) @@ -496,7 +490,7 @@ def preprocess( # initial probe complex_probe_rgb = Complex2RGB( - self.probe_centered[0], + self.probe_centered, vmin=vmin, vmax=vmax, hue_start=hue_start, @@ -517,40 +511,41 @@ def preprocess( 0, ] - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize) + fig, axs = plt.subplots(1, self._num_probes + 1, figsize=figsize) - ax1.imshow( - complex_probe_rgb, - extent=probe_extent, - **kwargs, - ) - - divider = make_axes_locatable(ax1) - cax1 = divider.append_axes("right", size="5%", pad="2.5%") - add_colorbar_arg( - cax1, vmin=vmin, vmax=vmax, hue_start=hue_start, invert=invert - ) - ax1.set_ylabel("x [A]") - ax1.set_xlabel("y [A]") - ax1.set_title("Initial Probe[0]") + for i in range(self._num_probes): + axs[i].imshow( + complex_probe_rgb[i], + extent=probe_extent, + **kwargs, + ) + axs[i].set_ylabel("x [A]") + axs[i].set_xlabel("y [A]") + axs[i].set_title(f"Initial Probe[{i}]") + + divider = make_axes_locatable(axs[i]) + cax = divider.append_axes("right", size="5%", pad="2.5%") + add_colorbar_arg( + cax, vmin=vmin, vmax=vmax, hue_start=hue_start, invert=invert + ) - ax2.imshow( + axs[-1].imshow( asnumpy(probe_overlap), extent=extent, cmap=cmap, **kwargs, ) - ax2.scatter( + axs[-1].scatter( self.positions[:, 1], self.positions[:, 0], s=2.5, color=(1, 0, 0, 1), ) - ax2.set_ylabel("x [A]") - ax2.set_xlabel("y [A]") - ax2.set_xlim((extent[0], extent[1])) - ax2.set_ylim((extent[2], extent[3])) - ax2.set_title("Object Field of View") + axs[-1].set_ylabel("x [A]") + axs[-1].set_xlabel("y [A]") + axs[-1].set_xlim((extent[0], extent[1])) + axs[-1].set_ylim((extent[2], extent[3])) + axs[-1].set_title("Object Field of View") fig.tight_layout() From b3bb16d5c639a849010a3754ae37b08dfb484b32 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sat, 17 Jun 2023 10:16:28 -0700 Subject: [PATCH 228/362] fixed read-write of corner-centered probes --- .../process/phase/iterative_base_class.py | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 2ad0a0927..04462c389 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -1210,6 +1210,15 @@ def to_h5(self, group): data=self._polar_parameters, ) + # object + self._object_emd = Array( + name="reconstruction_object", + data=asnumpy(self._xp.asarray(self._object)), + ) + + # probe + self._probe_emd = Array(name="reconstruction_probe", data=asnumpy(self._probe)) + if is_stack: iterations_labels = [f"iteration_{i:03}" for i in iterations] @@ -1217,32 +1226,20 @@ def to_h5(self, group): object_iterations = [ np.asarray(self.object_iterations[i]) for i in iterations ] - self._object_emd = Array( - name="reconstruction_object", + self._object_iterations_emd = Array( + name="reconstruction_object_iterations", data=np.stack(object_iterations, axis=0), slicelabels=iterations_labels, ) # probe probe_iterations = [self.probe_iterations[i] for i in iterations] - self._probe_emd = Array( - name="reconstruction_probe", + self._probe_iterations_emd = Array( + name="reconstruction_probe_iterations", data=np.stack(probe_iterations, axis=0), slicelabels=iterations_labels, ) - else: - # object - self._object_emd = Array( - name="reconstruction_object", - data=asnumpy(self._xp.asarray(self._object)), - ) - - # probe - self._probe_emd = Array( - name="reconstruction_probe", data=asnumpy(self._probe) - ) - # exit_waves if self._save_exit_waves: self._exit_waves_emd = Array( @@ -1283,13 +1280,8 @@ def _get_constructor_args(cls, group): else: dc = None - # Check if stack - if dict_data["_object_emd"].is_stack: - obj = dict_data["_object_emd"][-1].data - probe = dict_data["_probe_emd"][-1].data - else: - obj = dict_data["_object_emd"].data - probe = dict_data["_probe_emd"].data + obj = dict_data["_object_emd"].data + probe = dict_data["_probe_emd"].data # Populate args and return kwargs = { @@ -1347,8 +1339,8 @@ def _populate_instance(self, group): # Check if stack if hasattr(error, "__len__"): - self.object_iterations = list(dict_data["_object_emd"].data) - self.probe_iterations = list(dict_data["_probe_emd"].data) + self.object_iterations = list(dict_data["_object_iterations_emd"].data) + self.probe_iterations = list(dict_data["_probe_iterations_emd"].data) self.error_iterations = error self.error = error[-1] else: @@ -1357,7 +1349,7 @@ def _populate_instance(self, group): # Slim preprocessing to enable visualize self._positions_px_com = xp.mean(self._positions_px, axis=0) self.object = asnumpy(self._object) - self.probe = asnumpy(self._probe) + self.probe = self.probe_centered self._preprocessed = True def _set_polar_parameters(self, parameters: dict): @@ -1445,9 +1437,9 @@ def _calculate_scan_positions_in_pixels(self, positions: np.ndarray): self._object_padding_px = (float_padding, float_padding) elif np.isscalar(self._object_padding_px[0]): self._object_padding_px = ( - (self._object_padding_px[0],)*2, - (self._object_padding_px[1],)*2 - ) + (self._object_padding_px[0],) * 2, + (self._object_padding_px[1],) * 2, + ) positions[:, 0] += self._object_padding_px[0][0] positions[:, 1] += self._object_padding_px[1][0] From 0b56a40cf383349666f2d3ea5bd6b64409e83f5b Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 20 Jun 2023 16:08:48 -0700 Subject: [PATCH 229/362] re-introducing Fourier probe amplitude fixing --- .../iterative_ptychographic_constraints.py | 31 +++++++ .../iterative_singleslice_ptychography.py | 80 ++++++++++++------- 2 files changed, 80 insertions(+), 31 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 10b24eb78..274e86f39 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -486,6 +486,37 @@ def _probe_fourier_amplitude_constraint( return updated_probe * normalization + def _probe_aperture_constraint( + self, + current_probe, + initial_probe_aperture, + ): + """ + Ptychographic constraint to fix Fourier amplitude to initial aperture. + + Parameters + ---------- + current_probe: np.ndarray + Current positions estimate + + Returns + -------- + constrained_probe: np.ndarray + Constrained probe estimate + """ + xp = self._xp + + current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + current_probe_fft_phase = xp.angle(xp.fft.fft2(current_probe)) + + updated_probe = xp.fft.ifft2( + xp.exp(1j * current_probe_fft_phase) * initial_probe_aperture + ) + updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + + return updated_probe * normalization + def _probe_residual_aberration_filtering_constraint( self, current_probe, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 5ef8985c6..269a61180 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -446,6 +446,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -999,11 +1000,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1039,17 +1042,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1121,17 +1128,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1159,12 +1171,13 @@ def reconstruct( pure_phase_object_iter: int = 0, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1218,17 +1231,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -1564,13 +1579,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter From a0cfa8b8ab93ae5dea164d578e94843b054e0b96 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Wed, 21 Jun 2023 09:40:28 -0700 Subject: [PATCH 230/362] Fourier probe amplitude fixing in rest of classes --- .../iterative_mixedstate_ptychography.py | 69 +++++++------ .../iterative_multislice_ptychography.py | 80 ++++++++++------ .../iterative_overlap_magnetic_tomography.py | 94 +++++++++++------- .../phase/iterative_overlap_tomography.py | 96 +++++++++++-------- .../iterative_simultaneous_ptychography.py | 80 ++++++++++------ 5 files changed, 255 insertions(+), 164 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 4b2187a15..afa565871 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -459,6 +459,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = None # Doesn't really make sense for mixed-state self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1083,11 +1084,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1124,17 +1127,21 @@ def _constraints( If True, only the probe phase is smoothed symmetrize_probe: bool If True, the probe is radially-averaged - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray + initial probe aperture to use in replacing probe fourier amplitude fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1203,9 +1210,11 @@ def _constraints( raise NotImplementedError() if symmetrize_probe: raise NotImplementedError() - if fix_probe_amplitude: + if fix_probe_aperture: raise NotImplementedError() - elif fix_probe_fourier_amplitude: + elif constrain_probe_amplitude: + raise NotImplementedError() + elif constrain_probe_fourier_amplitude: raise NotImplementedError() if orthogonalize_probe: @@ -1237,12 +1246,13 @@ def reconstruct( fix_com: bool = True, orthogonalize_probe: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, @@ -1295,17 +1305,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -1637,13 +1649,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index ce8d13325..a67bd93e9 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -521,6 +521,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1432,11 +1433,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1477,17 +1480,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool + If True, probe Fourier amplitude is replaced by initial_probe_aperture + initial_probe_aperture: np.ndarray + Initial probe aperture to use in replacing probe Fourier amplitude fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1589,17 +1596,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1626,12 +1638,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1692,17 +1705,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2049,13 +2064,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 0ef7725a1..8e8484827 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -707,6 +707,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1662,11 +1663,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1704,17 +1707,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1813,17 +1820,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1850,12 +1862,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1912,17 +1925,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2398,14 +2413,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 - < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter @@ -2450,13 +2467,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 4a64f17af..6166640f4 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -616,6 +616,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -1510,11 +1511,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -1548,17 +1551,21 @@ def _constraints( Standard deviation of gaussian kernel in A^-1 probe_gaussian_filter_fix_amplitude: bool If True, only the probe phase is smoothed - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -1626,17 +1633,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -1663,12 +1675,13 @@ def reconstruct( positions_step_size: float = 0.9, fix_com: bool = True, fix_probe_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -1722,17 +1735,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional - Number of iterations to run with a fixed probe before updating probe estimate - fix_probe_amplitude: bool + Number of iterations to run before radially-averaging the probe + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2127,14 +2142,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 - < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter @@ -2174,13 +2191,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, global_affine_transformation=global_affine_transformation, gaussian_filter=a0 < gaussian_filter_iter diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index e872bc42e..da358e089 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -694,6 +694,7 @@ def preprocess( self._probe = xp.asarray(self._probe, dtype=xp.complex64) self._probe_initial = self._probe.copy() + self._probe_initial_aperture = xp.abs(xp.fft.fft2(self._probe)) self._known_aberrations_array = ComplexProbe( energy=self._energy, @@ -2181,11 +2182,13 @@ def _constraints( probe_gaussian_filter, probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude, - fix_probe_fourier_amplitude_threshold, + constrain_probe_amplitude, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude, + constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture, + initial_probe_aperture, fix_positions, global_affine_transformation, gaussian_filter, @@ -2219,17 +2222,21 @@ def _constraints( If True, probe CoM is fixed to the center symmetrize_probe: bool If True, the probe is radially-averaged - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. + fix_probe_aperture: bool, + If True, probe Fourier amplitude is replaced by initial probe aperture. + initial_probe_aperture: np.ndarray, + Initial probe aperture to use in replacing probe Fourier amplitude. fix_positions: bool If True, positions are not updated gaussian_filter: bool @@ -2335,17 +2342,22 @@ def _constraints( if symmetrize_probe: current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_amplitude: + if fix_probe_aperture: + current_probe = self._probe_aperture_constraint( + current_probe, + initial_probe_aperture, + ) + elif constrain_probe_amplitude: current_probe = self._probe_amplitude_constraint( current_probe, - fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width, + constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width, ) - elif fix_probe_fourier_amplitude: + elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - fix_probe_fourier_amplitude_threshold, - fix_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude_threshold, + constrain_probe_amplitude_relative_width, ) if not fix_positions: @@ -2374,12 +2386,13 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, warmup_iter: int = 0, + fix_probe_aperture_iter: int = 0, symmetrize_probe_iter: int = 0, - fix_probe_amplitude_iter: int = 0, - fix_probe_amplitude_relative_radius: float = 0.5, - fix_probe_amplitude_relative_width: float = 0.05, - fix_probe_fourier_amplitude_iter: int = 0, - fix_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_amplitude_iter: int = 0, + constrain_probe_amplitude_relative_radius: float = 0.5, + constrain_probe_amplitude_relative_width: float = 0.05, + constrain_probe_fourier_amplitude_iter: int = 0, + constrain_probe_fourier_amplitude_threshold: float = 0.9, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, @@ -2436,17 +2449,19 @@ def reconstruct( If True, fixes center of mass of probe fix_probe_iter: int, optional Number of iterations to run with a fixed probe before updating probe estimate + fix_probe_aperture_iter: int, optional + Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate symmetrize_probe_iter: int, optional Number of iterations to run before radially-averaging the probe - fix_probe_amplitude: bool + constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function - fix_probe_amplitude_relative_radius: float + constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 - fix_probe_amplitude_relative_width: float + constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - fix_probe_fourier_amplitude: bool + constrain_probe_fourier_amplitude: bool If True, probe fourier amplitude is constrained by top hat function - fix_probe_fourier_amplitude_threshold: float + constrain_probe_fourier_amplitude_threshold: float Threshold value for current probe fourier mask. Value should be between 0 and 1, where higher values provide the most masking. fix_positions_iter: int, optional @@ -2811,13 +2826,16 @@ def reconstruct( and probe_gaussian_filter_sigma is not None, probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, - fix_probe_amplitude=a0 < fix_probe_amplitude_iter + constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_amplitude_relative_radius=fix_probe_amplitude_relative_radius, - fix_probe_amplitude_relative_width=fix_probe_amplitude_relative_width, - fix_probe_fourier_amplitude=a0 < fix_probe_fourier_amplitude_iter + constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, + constrain_probe_amplitude_relative_width=constrain_probe_amplitude_relative_width, + constrain_probe_fourier_amplitude=a0 + < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - fix_probe_fourier_amplitude_threshold=fix_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + fix_probe_aperture=a0 < fix_probe_aperture_iter, + initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, global_affine_transformation=global_affine_transformation, warmup_iteration=a0 < warmup_iter, From c5ef1c39e290107742a4d89b5baea119b69af72b Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:18:58 -0400 Subject: [PATCH 231/362] propagate sampling overrides --- .../iterative_mixedstate_ptychography.py | 22 +++++++++++++- .../iterative_multislice_ptychography.py | 22 +++++++++++++- .../iterative_overlap_magnetic_tomography.py | 23 ++++++++++++++- .../phase/iterative_overlap_tomography.py | 23 ++++++++++++++- .../iterative_simultaneous_ptychography.py | 29 ++++++++++++++++++- .../iterative_singleslice_ptychography.py | 14 +++++---- 6 files changed, 122 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index afa565871..4dea8172f 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -52,7 +52,9 @@ class MixedstatePtychographicReconstruction(PtychographicReconstruction): num_probes: int, optional Number of mixed-state probes semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -91,6 +93,7 @@ def __init__( datacube: DataCube = None, num_probes: int = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -171,6 +174,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -196,6 +200,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -245,6 +252,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -289,6 +302,9 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -344,6 +360,10 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a67bd93e9..a9dcf2d41 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -56,7 +56,9 @@ class MultislicePtychographicReconstruction(PtychographicReconstruction): datacube: DataCube, optional Input 4D diffraction pattern intensities semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -99,6 +101,7 @@ def __init__( slice_thicknesses: Union[float, Sequence[float]], datacube: DataCube = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -175,6 +178,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -271,6 +275,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -320,6 +327,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -364,6 +377,9 @@ def preprocess( self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -419,6 +435,10 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 8e8484827..7831bd12a 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -63,7 +63,9 @@ class OverlapMagneticTomographicReconstruction(PtychographicReconstruction): - \beta tilt around x-axis - -\alpha tilt around z-axis semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -106,6 +108,7 @@ def __init__( tilt_angles_deg: Sequence[Tuple[float, float]], datacube: Sequence[DataCube] = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -171,6 +174,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -422,6 +426,9 @@ def preprocess( diffraction_patterns_transpose: bool = None, force_com_shifts: Sequence[float] = None, progress_bar: bool = True, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -458,6 +465,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. One tuple per tilt. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -551,6 +564,9 @@ def preprocess( intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube[tilt_index], require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -600,6 +616,11 @@ def preprocess( self._scan_positions[tilt_index] ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6166640f4..a55a08697 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -58,7 +58,9 @@ class OverlapTomographicReconstruction(PtychographicReconstruction): tilt_angles_deg: Sequence[float] List of tilt angles in degrees, semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -101,6 +103,7 @@ def __init__( tilt_angles_deg: Sequence[float], datacube: Sequence[DataCube] = None, semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -172,6 +175,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -331,6 +335,9 @@ def preprocess( diffraction_patterns_rotate_degrees: float = None, diffraction_patterns_transpose: bool = None, force_com_shifts: Sequence[float] = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, progress_bar: bool = True, object_fov_mask: np.ndarray = None, **kwargs, @@ -368,6 +375,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. One tuple per tilt. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -460,6 +473,9 @@ def preprocess( intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube[tilt_index], require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -509,6 +525,11 @@ def preprocess( self._scan_positions[tilt_index] ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index da358e089..ae302f660 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -53,7 +53,9 @@ class SimultaneousPtychographicReconstruction(PtychographicReconstruction): simultaneous_measurements_mode: str, optional One of '-+', '-0+', '0+', where -/0/+ refer to the sign of the magnetic potential semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -95,6 +97,7 @@ def __init__( datacube: Sequence[DataCube] = None, simultaneous_measurements_mode: str = "-+", semiangle_cutoff: float = None, + semiangle_cutoff_pixels: float = None, rolloff: float = 2.0, vacuum_probe_intensity: np.ndarray = None, polar_parameters: Mapping[str, float] = None, @@ -160,6 +163,7 @@ def __init__( self._scan_positions = initial_scan_positions self._energy = energy self._semiangle_cutoff = semiangle_cutoff + self._semiangle_cutoff_pixels = semiangle_cutoff_pixels self._rolloff = rolloff self._object_type = object_type self._object_padding_px = object_padding_px @@ -184,6 +188,9 @@ def preprocess( force_com_rotation: float = None, force_com_transpose: float = None, force_com_shifts: float = None, + force_scan_sampling: float = None, + force_angular_sampling: float = None, + force_reciprocal_sampling: float = None, object_fov_mask: np.ndarray = None, **kwargs, ): @@ -230,6 +237,12 @@ def preprocess( Amplitudes come from diffraction patterns shifted with the CoM in the upper left corner for each probe unless shift is overwritten. + force_scan_sampling: float, optional + Override DataCube real space scan pixel size calibrations, in Angstrom + force_angular_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in mrad + force_reciprocal_sampling: float, optional + Override DataCube reciprocal pixel size calibration, in A^-1 object_fov_mask: np.ndarray (boolean) Boolean mask of FOV. Used to calculate additional shrinkage of object If None, probe_overlap intensity is thresholded @@ -344,6 +357,9 @@ def preprocess( intensities_0 = self._extract_intensities_and_calibrations_from_datacube( measurement_0, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -424,6 +440,9 @@ def preprocess( intensities_1 = self._extract_intensities_and_calibrations_from_datacube( measurement_1, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -505,6 +524,9 @@ def preprocess( intensities_2 = self._extract_intensities_and_calibrations_from_datacube( measurement_2, require_calibrations=True, + force_scan_sampling=force_scan_sampling, + force_angular_sampling=force_angular_sampling, + force_reciprocal_sampling=force_reciprocal_sampling, ) ( @@ -591,6 +613,11 @@ def preprocess( self._scan_positions ) + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 269a61180..494d97119 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -50,7 +50,9 @@ class SingleslicePtychographicReconstruction(PtychographicReconstruction): datacube: DataCube Input 4D diffraction pattern intensities semiangle_cutoff: float, optional - Semiangle cutoff for the initial probe guess + Semiangle cutoff for the initial probe guess in mrad + semiangle_cutoff_pixels: float, optional + Semiangle cutoff for the initial probe guess in pixels rolloff: float, optional Semiangle rolloff for the initial probe guess vacuum_probe_intensity: np.ndarray, optional @@ -289,11 +291,6 @@ def preprocess( force_reciprocal_sampling=force_reciprocal_sampling, ) - # handle semiangle specified in pixels - if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - - ( self._com_measured_x, self._com_measured_y, @@ -346,6 +343,11 @@ def preprocess( self._positions_px = self._calculate_scan_positions_in_pixels( self._scan_positions ) + + # handle semiangle specified in pixels + if self._semiangle_cutoff_pixels: + self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + # Object Initialization if self._object is None: pad_x = self._object_padding_px[0][1] From df86a73da87ca484b2dcf7dd7e7cc22f10f6811b Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:21:25 -0400 Subject: [PATCH 232/362] format with black --- .../process/phase/iterative_base_class.py | 20 ++++++++++++------- .../iterative_mixedstate_ptychography.py | 4 +++- .../iterative_multislice_ptychography.py | 4 +++- .../iterative_overlap_magnetic_tomography.py | 5 +++-- .../phase/iterative_overlap_tomography.py | 5 +++-- .../iterative_simultaneous_ptychography.py | 5 +++-- .../iterative_singleslice_ptychography.py | 4 +++- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 04462c389..766d03c6a 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -199,7 +199,7 @@ def _preprocess_datacube_and_vacuum_probe( output_size=diffraction_intensities_shape, force_nonnegative=True, ) - + if probe_roi_shape is not None: Qx, Qy = datacube.shape[-2:] Sx, Sy = probe_roi_shape @@ -325,9 +325,9 @@ def _extract_intensities_and_calibrations_from_datacube( # there is no xor keyword in Python! angular = force_angular_sampling is not None reciprocal = force_reciprocal_sampling is not None - assert (angular and not reciprocal) or (not angular and reciprocal), ( - "Only one of angular or reciprocal calibration can be forced!" - ) + assert (angular and not reciprocal) or ( + not angular and reciprocal + ), "Only one of angular or reciprocal calibration can be forced!" # angular calibration specified if angular: @@ -336,7 +336,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._reciprocal_sampling = ( - force_angular_sampling / electron_wavelength_angstrom(self._energy) / 1e3, + force_angular_sampling + / electron_wavelength_angstrom(self._energy) + / 1e3, ) * 2 self._reciprocal_units = ("A^-1",) * 2 @@ -347,7 +349,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._angular_sampling = ( - force_reciprocal_sampling * electron_wavelength_angstrom(self._energy) * 1e3, + force_reciprocal_sampling + * electron_wavelength_angstrom(self._energy) + * 1e3, ) * 2 self._angular_units = ("mrad",) * 2 @@ -378,7 +382,9 @@ def _extract_intensities_and_calibrations_from_datacube( if self._energy is not None: self._angular_sampling = ( - reciprocal_size * electron_wavelength_angstrom(self._energy) * 1e3, + reciprocal_size + * electron_wavelength_angstrom(self._energy) + * 1e3, ) * 2 self._angular_units = ("mrad",) * 2 diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 4dea8172f..8d4574aa4 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -362,7 +362,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index a9dcf2d41..36b44b77e 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -437,7 +437,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 7831bd12a..9d4acfc4c 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -618,8 +618,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index a55a08697..82d1caac3 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -527,8 +527,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index ae302f660..9e4b39cf5 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -615,8 +615,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] - + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 494d97119..52aa2f816 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -346,7 +346,9 @@ def preprocess( # handle semiangle specified in pixels if self._semiangle_cutoff_pixels: - self._semiangle_cutoff = self._semiangle_cutoff_pixels * self._angular_sampling[0] + self._semiangle_cutoff = ( + self._semiangle_cutoff_pixels * self._angular_sampling[0] + ) # Object Initialization if self._object is None: From f0be6cbfa0779e6b84b2286fd4a2d20c537bbc89 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:45:10 -0400 Subject: [PATCH 233/362] first attempt at caching preprocessed object if not optimized --- py4DSTEM/process/phase/parameter_optimize.py | 30 ++++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 987ffedef..ee8473be1 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -294,17 +294,35 @@ def _get_optimization_function( dictionary are used. """ - # Construct partial methods to encapsulate the static parameters - obj = partial(cls, **init_static_args) - affine = partial(AffineTransform, **affine_static_args) - prep = partial(cls.preprocess, **preprocess_static_args) - recon = partial(cls.reconstruct, **reconstruct_static_args) - + # Get lists of optimization parameters for each step init_params = list(init_optimization_params.keys()) afft_params = list(affine_optimization_params.keys()) prep_params = list(preprocess_optimization_params.keys()) reco_params = list(reconstruct_optimization_params.keys()) + # Construct partial methods to encapsulate the static parameters. + # If only ``reconstruct`` has optimization variables, perform + # preprocessing now, store the ptycho object, and use dummy + # functions instead of the partials + if (len(init_params),len(afft_params),len(prep_params)) == (0,0,0): + affine_preprocessed = AffineTransform(**affine_static_args) + init_args = init_static_args.copy() + init_args["initial_scan_positions"] = self._get_scan_positions(affine_preprocessed, init_static_args["datacube"]) + + ptycho_preprocessed = cls.__init__(**init_args).preprocess(**preprocess_static_args) + + def obj(**kwargs): + return ptycho_preprocessed + def prep(ptycho,**kwargs): + return ptycho + + else: + obj = partial(cls, **init_static_args) + affine = partial(AffineTransform, **affine_static_args) + prep = partial(cls.preprocess, **preprocess_static_args) + + recon = partial(cls.reconstruct, **reconstruct_static_args) + # Target function for Gaussian process optimization that takes a single # dict of named parameters and returns the ptycho error metric @use_named_args(parameter_list) From 9f3686d1b288d6f0ade767802048b019a75b4ec7 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 13:45:32 -0400 Subject: [PATCH 234/362] format with black --- py4DSTEM/process/phase/parameter_optimize.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ee8473be1..292df27b6 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -304,16 +304,21 @@ def _get_optimization_function( # If only ``reconstruct`` has optimization variables, perform # preprocessing now, store the ptycho object, and use dummy # functions instead of the partials - if (len(init_params),len(afft_params),len(prep_params)) == (0,0,0): + if (len(init_params), len(afft_params), len(prep_params)) == (0, 0, 0): affine_preprocessed = AffineTransform(**affine_static_args) init_args = init_static_args.copy() - init_args["initial_scan_positions"] = self._get_scan_positions(affine_preprocessed, init_static_args["datacube"]) + init_args["initial_scan_positions"] = self._get_scan_positions( + affine_preprocessed, init_static_args["datacube"] + ) - ptycho_preprocessed = cls.__init__(**init_args).preprocess(**preprocess_static_args) + ptycho_preprocessed = cls.__init__(**init_args).preprocess( + **preprocess_static_args + ) def obj(**kwargs): return ptycho_preprocessed - def prep(ptycho,**kwargs): + + def prep(ptycho, **kwargs): return ptycho else: From 2ced4e5e4ea7dc9fc06e237c58ecf4d87c967b4b Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 24 Jun 2023 15:04:18 -0400 Subject: [PATCH 235/362] preprocess caching bug fixed --- py4DSTEM/process/phase/parameter_optimize.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 292df27b6..2e52a677a 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -311,7 +311,7 @@ def _get_optimization_function( affine_preprocessed, init_static_args["datacube"] ) - ptycho_preprocessed = cls.__init__(**init_args).preprocess( + ptycho_preprocessed = cls(**init_args).preprocess( **preprocess_static_args ) @@ -323,9 +323,9 @@ def prep(ptycho, **kwargs): else: obj = partial(cls, **init_static_args) - affine = partial(AffineTransform, **affine_static_args) prep = partial(cls.preprocess, **preprocess_static_args) + affine = partial(AffineTransform, **affine_static_args) recon = partial(cls.reconstruct, **reconstruct_static_args) # Target function for Gaussian process optimization that takes a single @@ -364,6 +364,7 @@ def _set_optimizer_defaults(self): self._reconstruction_static_args["progress_bar"] = False self._reconstruction_static_args["store_iterations"] = False + self._reconstruction_static_args["reset"] = True class OptimizationParameter: From 258c9cddaa4f3735d53b89afd3dea933344e5810 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sun, 25 Jun 2023 13:05:14 -0400 Subject: [PATCH 236/362] use log error for optimizer --- py4DSTEM/process/phase/parameter_optimize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 2e52a677a..3676616a4 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -348,7 +348,7 @@ def f(**kwargs): prep(ptycho, **prep_args) recon(ptycho, **reco_args) - return ptycho.error + return np.log(ptycho.error) return f From a67305a38dcaa0fb10416099c385ad35e7537a51 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 1 Jun 2023 13:56:32 -0700 Subject: [PATCH 237/362] doc strings modification --- py4DSTEM/process/phase/parameter_optimize.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 3676616a4..33f566fe6 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -43,9 +43,11 @@ def __init__( Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial scan positions), preprocess, and reconstruct are required. For parameters not optimized over, the value in the dictionary is used. To optimize a parameter, instead pass an - OptimizationParameter object inside the dictionary to specify the bounds, initial guess, - and type of parameter. Calling optimize will then run the optimization simultaneously - over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments + OptimizationParameter object inside the dictionary to specify the initial guess, bounds, + and type of parameter, for example: + >>> 'param':OptimizationParameter(initial guess, lower bound, upper bound) + Calling optimize will then run the optimization simultaneously over all + optimization parameters. To obtain the optimized parameters, call get_optimized_arguments to return a set of dictionaries where the OptimizationParameter objects have been replaced with the optimal values. These can then be modified for running a full reconstruction. From 18b583c797c3d6a49d4ed1f6d7d292dcea33acd3 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 5 Jun 2023 11:31:39 -0700 Subject: [PATCH 238/362] no empty dictionaries required! --- py4DSTEM/process/phase/parameter_optimize.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 33f566fe6..f0631694d 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -30,9 +30,9 @@ def __init__( self, reconstruction_type: type[PhaseReconstruction], init_args: dict, - affine_args: dict, preprocess_args: dict, reconstruction_args: dict, + affine_args: dict = None, ): """ Parameter optimization for ptychographic reconstruction based on Bayesian Optimization @@ -43,10 +43,10 @@ def __init__( Dictionaries of the arguments to __init__, AffineTransform (for distorting the initial scan positions), preprocess, and reconstruct are required. For parameters not optimized over, the value in the dictionary is used. To optimize a parameter, instead pass an - OptimizationParameter object inside the dictionary to specify the initial guess, bounds, - and type of parameter, for example: + OptimizationParameter object inside the dictionary to specify the initial guess, bounds, + and type of parameter, for example: >>> 'param':OptimizationParameter(initial guess, lower bound, upper bound) - Calling optimize will then run the optimization simultaneously over all + Calling optimize will then run the optimization simultaneously over all optimization parameters. To obtain the optimized parameters, call get_optimized_arguments to return a set of dictionaries where the OptimizationParameter objects have been replaced with the optimal values. These can then be modified for running a full reconstruction. @@ -57,14 +57,16 @@ def __init__( Type of ptychographic reconstruction to perform init_args: dict Keyword arguments passed to the __init__ method of the reconstruction class - affine_args: dict - Keyword arguments passed to AffineTransform. The transform is applied to the initial - scan positions. preprocess_args: dict Keyword arguments passed to the preprocess method the reconstruction object reconstruction_args: dict Keyword arguments passed to the reconstruct method the the reconstruction object + affine_args: dict + Keyword arguments passed to AffineTransform. The transform is applied to the initial + scan positions. """ + if affine_args is None: + affine_args = {} # loop over each argument dictionary and split into static and optimization variables ( From 559d79ec7dc7bd57cc1cafa70f666413f3e9b00c Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Thu, 29 Jun 2023 17:35:17 -0400 Subject: [PATCH 239/362] add skopt to dependencies --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index b97e84882..cb9da8169 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ 'matplotlib >= 3.2.2', 'scikit-image >= 0.17.2', 'scikit-learn >= 0.23.2', + 'scikit-optimize >= 0.9.0', 'tqdm >= 4.46.1', 'dill >= 0.3.3', 'gdown >= 4.4.0', From 62f8d3f49210c6abfb654022973e2a7e06e9d946 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Sat, 1 Jul 2023 15:44:55 -0400 Subject: [PATCH 240/362] add custom error metrics for ptycho optimizer --- py4DSTEM/process/phase/parameter_optimize.py | 102 +++++++++++++++++-- 1 file changed, 95 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index f0631694d..ddc51f57b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -12,7 +12,7 @@ import numpy as np from functools import partial -from typing import Union +from typing import Union, Callable from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction from py4DSTEM.process.phase.utils import AffineTransform @@ -109,8 +109,9 @@ def __init__( def optimize( self, - n_calls: int, - n_initial_points: int, + n_calls: int = 50, + n_initial_points: int = 20, + error_metric: Union[Callable, str] = "log", **skopt_kwargs: dict, ): """ @@ -123,10 +124,29 @@ def optimize( n_initial_points: int Number of uniformly spaced trial points to test before beginning Bayesian optimization (must be less than n_calls) + error_metric: Callable or str + Function used to compute the reconstruction error. + When passed as a string, may be one of: + 'log': log(NMSE) of final object + 'linear': NMSE of final object + 'log-converged': log(NMSE) of final object if + NMSE is decreasing, 0 if NMSE increasing + 'linear-converged': NMSE of final object if + NMSE is decreasing, 1 if NMSE increasing + 'TV': sum( abs( grad( object ) ) ) / sum( abs( object ) ) + 'std': negative standard deviation of cropped object + 'std-phase': negative standard deviation of + phase of the cropped object + When passed as a Callable, a function that takes the + PhaseReconstruction object as its only argument + and returns the error metric as a single float skopt_kwargs: dict Additional arguments to be passed to skopt.gp_minimize """ + + error_metric = self._get_error_metric(error_metric) + self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, @@ -139,6 +159,7 @@ def optimize( self._affine_optimize_args, self._preprocess_optimize_args, self._reconstruction_optimize_args, + error_metric, ) # Make a progress bar @@ -272,6 +293,74 @@ def _get_scan_positions(self, affine_transform, dataset): scan_positions = scan_positions @ affine_transform.asarray() return scan_positions + def _get_error_metric(self, error_metric: Union[Callable, str]) -> Callable: + """ + Get error metric as a function, converting builtin method names + to functions + """ + + if callable(error_metric): + return error_metric + + assert error_metric in ( + "log", + "linear", + "log-converged", + "linear-converged", + "TV", + "std", + "std-phase", + ), f"Error metric {error_metric} not recognized." + + if error_metric == "log": + + def f(ptycho): + return np.log(ptycho.error) + + elif error_metric == "linear": + + def f(ptycho): + return ptycho.error + + elif error_metric == "log-converged": + + def f(ptycho): + converged = ptycho.error_iterations[-1] <= np.min( + ptycho.error_iterations + ) + return np.log(ptycho.error) if converged else 0.0 + + elif error_metric == "log-linear": + + def f(ptycho): + converged = ptycho.error_iterations[-1] <= np.min( + ptycho.error_iterations + ) + return ptycho.error if converged else 1.0 + + elif error_metric == "TV": + + def f(ptycho): + gx, gy = np.gradient(ptycho.object_cropped, axis=(-2, -1)) + obj_mag = np.sum(np.abs(ptycho.object_cropped)) + tv = np.sum(np.abs(gx)) + np.sum(np.abs(gy)) + return tv / obj_mag + + elif error_metric == "std": + + def f(ptycho): + return -np.std(ptycho.object_cropped) + + elif error_metric == "std-phase": + + def f(ptycho): + return -np.std(np.angle(ptycho.object_cropped)) + + else: + raise ValueError(f"Error metric {error_metric} not recognized.") + + return f + def _get_optimization_function( self, cls: type[PhaseReconstruction], @@ -285,6 +374,7 @@ def _get_optimization_function( affine_optimization_params: dict, preprocess_optimization_params: dict, reconstruct_optimization_params: dict, + error_metric: Callable, ): """ Wrap the ptychography pipeline into a single function that encapsulates all of the @@ -315,9 +405,7 @@ def _get_optimization_function( affine_preprocessed, init_static_args["datacube"] ) - ptycho_preprocessed = cls(**init_args).preprocess( - **preprocess_static_args - ) + ptycho_preprocessed = cls(**init_args).preprocess(**preprocess_static_args) def obj(**kwargs): return ptycho_preprocessed @@ -352,7 +440,7 @@ def f(**kwargs): prep(ptycho, **prep_args) recon(ptycho, **reco_args) - return np.log(ptycho.error) + return error_metric(ptycho) return f From 1b968dbb3a2ec9cb6447bae3f4c98c7a3e8e1999 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:27:41 -0400 Subject: [PATCH 241/362] docstring clarification Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ddc51f57b..998400843 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -21,9 +21,8 @@ class PtychographyOptimizer: """ Optimize ptychographic hyperparameters with Bayesian Optimization of a - Gaussian process. Any of the arguments to the ptychographic - init-preprocess-reconstruct pipeline can be optimized over (including - boolean or other flag options) + Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical + arguments to the ptychographic init-preprocess-reconstruct pipeline can be optimized over. """ def __init__( From 1ad12120ac13b5b6acd3e722125c2227a5a85675 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:33:22 -0400 Subject: [PATCH 242/362] remove unused argument Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 998400843..f3530491c 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -364,7 +364,6 @@ def _get_optimization_function( self, cls: type[PhaseReconstruction], parameter_list: list, - n_iterations: int, init_static_args: dict, affine_static_args: dict, preprocess_static_args: dict, From 887aa80208fc5e65b319574b2d13da2b9717aea0 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:34:43 -0400 Subject: [PATCH 243/362] remove another unused argument Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index f3530491c..ccc700ec9 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -149,7 +149,6 @@ def optimize( self._optimization_function = self._get_optimization_function( self._reconstruction_type, self._parameter_list, - n_calls, self._init_static_args, self._affine_static_args, self._preprocess_static_args, From bc28d5f3294a81ae65d20bf23342aa84efb2d86d Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:37:14 -0400 Subject: [PATCH 244/362] update plot function Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 81 +++++++++++++++----- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index ccc700ec9..d5aa580a9 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -189,37 +189,78 @@ def callback(*args, **kwargs): def visualize( self, - gp_model=True, - convergence=False, - objective=True, - evaluations=False, + plot_gp_model=True, + plot_convergence=False, + plot_objective=True, + plot_evaluations=False, + **kwargs, ): """ Visualize optimization results Parameters ---------- - gp_model: bool + plot_gp_model: bool Display fitted Gaussian process model (only available for 1-dimensional problem) - convergence: bool + plot_convergence: bool Display convergence history - objective: bool + plot_objective: bool Display GP objective function and partial dependence plots - evaluations: bool + plot_evaluations: bool Display histograms of sampled points + kwargs: + Passed directly to the skopt plot_gassian_process/plot_objective """ - if (len(self._parameter_list) == 1) and gp_model: - plot_gaussian_process(self._skopt_result) - plt.show() - if convergence: - plot_convergence(self._skopt_result) - plt.show() - if objective: - plot_objective(self._skopt_result) - plt.show() - if evaluations: - plot_evaluations(self._skopt_result) - plt.show() + ndims = len(self._parameter_list) + if ndims == 1: + if plot_convergence: + figsize = kwargs.pop("figsize", (9, 9)) + spec = GridSpec(nrows=2,ncols=1,height_ratios=[2,1], hspace=0.15) + else: + figsize = kwargs.pop("figsize", (9, 6)) + spec = GridSpec(nrows=1,ncols=1) + + fig = plt.figure(figsize = figsize) + ax = fig.add_subplot(spec[0]) + skopt_plot_gaussian_process(self._skopt_result,ax=ax, **kwargs) + + if plot_convergence: + ax = fig.add_subplot(spec[1]) + skopt_plot_convergence(self._skopt_result,ax=ax) + + else: + if plot_convergence: + figsize = kwargs.pop("figsize", (4*ndims, 4*(ndims+0.5))) + spec = GridSpec(nrows=ndims+1,ncols=ndims,height_ratios=[2]*ndims+[1], hspace=0.15) + else: + figsize = kwargs.pop("figsize", (4*ndims, 4*ndims)) + spec = GridSpec(nrows=ndims,ncols=ndims, hspace=0.15) + + if plot_evaluations: + axs = skopt_plot_evaluations(self._skopt_result) + elif plot_objective: + cmap = kwargs.pop("cmap", 'magma') + axs = skopt_plot_objective(self._skopt_result, cmap=cmap,**kwargs) + elif plot_convergence: + skopt_plot_convergence(self._skopt_result) + return self + + fig = axs[0,0].figure + fig.set_size_inches(figsize) + for i in range(ndims): + for j in range(ndims): + ax = axs[i,j] + ax.remove() + ax.figure = fig + fig.add_axes(ax) + ax.set_subplotspec(spec[i,j]) + + if plot_convergence: + ax = fig.add_subplot(spec[ndims,:]) + skopt_plot_convergence(self._skopt_result,ax=ax) + + spec.tight_layout(fig) + return self def get_optimized_arguments(self): From 43a580e947b3ad4a4673fdd8b7ec0b3fd329e286 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:37:35 -0400 Subject: [PATCH 245/362] update plot imports Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index d5aa580a9..1485b5edf 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -2,10 +2,10 @@ from skopt import gp_minimize from skopt.space import Real, Integer, Categorical from skopt.plots import ( - plot_convergence, - plot_gaussian_process, - plot_evaluations, - plot_objective, + plot_convergence as skopt_plot_convergence, + plot_gaussian_process as skopt_plot_gaussian_process, + plot_evaluations as skopt_plot_evaluations, + plot_objective as skopt_plot_objective, ) from skopt.utils import use_named_args import matplotlib.pyplot as plt From 7ccb46ce3e54aa0bb70af82efa2243b3ed07ef59 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:38:59 -0400 Subject: [PATCH 246/362] aesthetic preferences regarding asserts Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 1485b5edf..e46361a86 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -529,12 +529,9 @@ def __init__( """ # Check input space = space.lower() - assert space in ( - "real", - "integer", - "bool", - "categorical", - ), f"Unknown Parameter type: {space}" + if space not in ("real", "integer", "bool", "categorical"): + raise ValueError(f"Unknown Parameter type: {space}") + scaling = scaling.lower() assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" From 0155fd05a342f51f08787dc3d94d2de2197ad009 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:39:21 -0400 Subject: [PATCH 247/362] being less assertive Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index e46361a86..3ca9f53bd 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -534,7 +534,8 @@ def __init__( scaling = scaling.lower() - assert scaling in ("uniform", "log-uniform"), f"Unknown scaling: {scaling}" + if scaling not in ("uniform", "log-uniform"): + raise ValueError(f"Unknown scaling: {scaling}") # Get the right scikit-optimize class space_map = { From af6f2dcf375a4b7e75ca5952eb480e420d33b9a6 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:39:51 -0400 Subject: [PATCH 248/362] you wouldn't raise an AssertionError Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 3ca9f53bd..db9477d2b 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -550,6 +550,8 @@ def __init__( if space == "bool": categories = [True, False] + if not categories: + raise ValueError("Empty list of categories!") # store necessary information self._initial_value = initial_value self._categories = categories From 506e129704a21020c1a67e00efcb72370d80d39f Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Sun, 2 Jul 2023 15:40:23 -0400 Subject: [PATCH 249/362] remove another assert Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index db9477d2b..74be59373 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -563,7 +563,6 @@ def __init__( def _get(self, name): self._name = name if self._param_type is Categorical: - assert self._categories is not None, "Empty list of categories!" self._skopt_param = self._param_type( name=self._name, categories=self._categories ) From 1b9c5c372ca8ac9123051e9595c9e477d3ea661d Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 08:50:26 -0400 Subject: [PATCH 250/362] fix for george's suggestion --- py4DSTEM/process/phase/parameter_optimize.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 74be59373..b298b0017 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -550,8 +550,9 @@ def __init__( if space == "bool": categories = [True, False] - if not categories: + if categories == [] and space in ("categorical", "bool"): raise ValueError("Empty list of categories!") + # store necessary information self._initial_value = initial_value self._categories = categories From 14d8f2d3bbcaf28c3529c8b00013b29ef48a1ca4 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 17:04:29 -0400 Subject: [PATCH 251/362] add entropy metric, not sure if correct --- py4DSTEM/process/phase/parameter_optimize.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index b298b0017..0badf4ccd 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -9,6 +9,7 @@ ) from skopt.utils import use_named_args import matplotlib.pyplot as plt +from matplotlib.gridspec import GridSpec import numpy as np from functools import partial @@ -349,6 +350,7 @@ def _get_error_metric(self, error_metric: Union[Callable, str]) -> Callable: "TV", "std", "std-phase", + "entropy-phase", ), f"Error metric {error_metric} not recognized." if error_metric == "log": @@ -395,6 +397,15 @@ def f(ptycho): def f(ptycho): return -np.std(np.angle(ptycho.object_cropped)) + elif error_metric == "entropy-phase": + def f(ptycho): + obj = np.angle(ptycho.object_cropped) + gx,gy = np.gradient(obj) + ghist,_,_ = np.histogram2d(gx.ravel(),gy.ravel(),bins=obj.shape,density=True) + nz = ghist > 0 + S = np.sum(ghist[nz] * np.log2(ghist[nz])) + return S + else: raise ValueError(f"Error metric {error_metric} not recognized.") From 9b4fd0b12d999c73e71bbc873b91afde3b18eb74 Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 3 Jul 2023 17:05:10 -0400 Subject: [PATCH 252/362] docstring --- py4DSTEM/process/phase/parameter_optimize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 0badf4ccd..96ef07f15 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -137,6 +137,8 @@ def optimize( 'std': negative standard deviation of cropped object 'std-phase': negative standard deviation of phase of the cropped object + 'entropy-phase': entropy of the phase of the + cropped object When passed as a Callable, a function that takes the PhaseReconstruction object as its only argument and returns the error metric as a single float From 4a4dea9a0a9eb999acc1969e58628910722cc2e4 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:24:52 -0400 Subject: [PATCH 253/362] change how optimized dict is assembled Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 43 +++++++------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 96ef07f15..5785fe792 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -277,12 +277,14 @@ def get_optimized_arguments(self): where the OptimizationParameter items have been replaced with the optimal values obtained from the optimizer """ - init_opt = self._replace_optimized_parameters( - self._init_args, self._parameter_list - ) - affine_opt = self._replace_optimized_parameters( - self._affine_args, self._parameter_list - ) + optimized_dict = {p.name: v for p,v in zip(self._parameter_list,self._skopt_result.x)} + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._init_args } + init_opt = self._init_args | filtered_dict + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._affine_args } + affine_opt = self._affine_args | filtered_dict + affine_transform = partial(AffineTransform, **self._affine_static_args)( **affine_opt ) @@ -290,30 +292,15 @@ def get_optimized_arguments(self): affine_transform, init_opt["datacube"] ) init_opt["initial_scan_positions"] = scan_positions - - prep_opt = self._replace_optimized_parameters( - self._preprocess_args, self._parameter_list - ) - reco_opt = self._replace_optimized_parameters( - self._reconstruction_args, self._parameter_list - ) - + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._preprocess_args } + prep_opt = self._preprocess_args | filtered_dict + + filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._reconstruction_args } + reco_opt = self._reconstruction_args | filtered_dict + return init_opt, prep_opt, reco_opt - def _replace_optimized_parameters(self, arg_dict, parameters): - opt_args = {} - for k, v in arg_dict.items(): - # Check for optimization parameters - if isinstance(v, OptimizationParameter): - # Find the right parameter in the list - # There is probably a better way to do this inverse mapping! - for i, p in enumerate(parameters): - if p.name == k: - opt_args[k] = self._skopt_result.x[i] - else: - opt_args[k] = v - return opt_args - def _split_static_and_optimization_vars(self, argdict): static_args = {} optimization_args = {} From e82a8299459114c5aed4c0b4adeb88730546d3a9 Mon Sep 17 00:00:00 2001 From: Steve Zeltmann <37132012+sezelt@users.noreply.github.com> Date: Thu, 6 Jul 2023 18:44:09 -0400 Subject: [PATCH 254/362] add option to override default arguments to ptycho Co-authored-by: Georgios Varnavides --- py4DSTEM/process/phase/parameter_optimize.py | 26 +++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 5785fe792..09296126f 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -482,19 +482,27 @@ def f(**kwargs): return f - def _set_optimizer_defaults(self): + def _set_optimizer_defaults( + verbose = False, + plot_center_of_mass = False, + plot_rotation = False, + plot_probe_overlaps = False, + progress_bar = False, + store_iterations = False, + reset = True, + ): """ - Set all of the verbose and plotting to False + Set all of the verbose and plotting to False, allowing for user-overwrite. """ - self._init_static_args["verbose"] = False + self._init_static_args["verbose"] = verbose - self._preprocess_static_args["plot_center_of_mass"] = False - self._preprocess_static_args["plot_rotation"] = False - self._preprocess_static_args["plot_probe_overlaps"] = False + self._preprocess_static_args["plot_center_of_mass"] = plot_center_of_mass + self._preprocess_static_args["plot_rotation"] = plot_rotation + self._preprocess_static_args["plot_probe_overlaps"] = plot_probe_overlaps - self._reconstruction_static_args["progress_bar"] = False - self._reconstruction_static_args["store_iterations"] = False - self._reconstruction_static_args["reset"] = True + self._reconstruction_static_args["progress_bar"] = progress_bar + self._reconstruction_static_args["store_iterations"] = store_iterations + self._reconstruction_static_args["reset"] = reset class OptimizationParameter: From a0964ca97c83e3128eb3323a1e3c7e1b7018829f Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Thu, 6 Jul 2023 18:47:24 -0400 Subject: [PATCH 255/362] bugfix in optimizer defaults --- py4DSTEM/process/phase/parameter_optimize.py | 1 + 1 file changed, 1 insertion(+) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 09296126f..53e2222d3 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -483,6 +483,7 @@ def f(**kwargs): return f def _set_optimizer_defaults( + self, verbose = False, plot_center_of_mass = False, plot_rotation = False, From d70a22a72326ec491198ef7e04f24f8e951a3b4b Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 08:59:18 -0700 Subject: [PATCH 256/362] ptychoptimize formatting --- py4DSTEM/process/phase/__init__.py | 1 + py4DSTEM/process/phase/parameter_optimize.py | 97 ++++++++++++-------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index 207e44b56..ee542524f 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -10,5 +10,6 @@ from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction +from py4DSTEM.process.phase.utils import OptimizationParameter, PtychographyOptimizer # fmt: on diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index 53e2222d3..c8a51171d 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -22,7 +22,7 @@ class PtychographyOptimizer: """ Optimize ptychographic hyperparameters with Bayesian Optimization of a - Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical + Gaussian process. Any of the scalar-valued real or integer, boolean, or categorical arguments to the ptychographic init-preprocess-reconstruct pipeline can be optimized over. """ @@ -137,7 +137,7 @@ def optimize( 'std': negative standard deviation of cropped object 'std-phase': negative standard deviation of phase of the cropped object - 'entropy-phase': entropy of the phase of the + 'entropy-phase': entropy of the phase of the cropped object When passed as a Callable, a function that takes the PhaseReconstruction object as its only argument @@ -218,49 +218,54 @@ def visualize( if ndims == 1: if plot_convergence: figsize = kwargs.pop("figsize", (9, 9)) - spec = GridSpec(nrows=2,ncols=1,height_ratios=[2,1], hspace=0.15) + spec = GridSpec(nrows=2, ncols=1, height_ratios=[2, 1], hspace=0.15) else: figsize = kwargs.pop("figsize", (9, 6)) - spec = GridSpec(nrows=1,ncols=1) + spec = GridSpec(nrows=1, ncols=1) - fig = plt.figure(figsize = figsize) + fig = plt.figure(figsize=figsize) ax = fig.add_subplot(spec[0]) - skopt_plot_gaussian_process(self._skopt_result,ax=ax, **kwargs) + skopt_plot_gaussian_process(self._skopt_result, ax=ax, **kwargs) if plot_convergence: ax = fig.add_subplot(spec[1]) - skopt_plot_convergence(self._skopt_result,ax=ax) + skopt_plot_convergence(self._skopt_result, ax=ax) else: if plot_convergence: - figsize = kwargs.pop("figsize", (4*ndims, 4*(ndims+0.5))) - spec = GridSpec(nrows=ndims+1,ncols=ndims,height_ratios=[2]*ndims+[1], hspace=0.15) + figsize = kwargs.pop("figsize", (4 * ndims, 4 * (ndims + 0.5))) + spec = GridSpec( + nrows=ndims + 1, + ncols=ndims, + height_ratios=[2] * ndims + [1], + hspace=0.15, + ) else: - figsize = kwargs.pop("figsize", (4*ndims, 4*ndims)) - spec = GridSpec(nrows=ndims,ncols=ndims, hspace=0.15) + figsize = kwargs.pop("figsize", (4 * ndims, 4 * ndims)) + spec = GridSpec(nrows=ndims, ncols=ndims, hspace=0.15) if plot_evaluations: axs = skopt_plot_evaluations(self._skopt_result) elif plot_objective: - cmap = kwargs.pop("cmap", 'magma') - axs = skopt_plot_objective(self._skopt_result, cmap=cmap,**kwargs) + cmap = kwargs.pop("cmap", "magma") + axs = skopt_plot_objective(self._skopt_result, cmap=cmap, **kwargs) elif plot_convergence: skopt_plot_convergence(self._skopt_result) return self - fig = axs[0,0].figure + fig = axs[0, 0].figure fig.set_size_inches(figsize) for i in range(ndims): for j in range(ndims): - ax = axs[i,j] + ax = axs[i, j] ax.remove() ax.figure = fig fig.add_axes(ax) - ax.set_subplotspec(spec[i,j]) + ax.set_subplotspec(spec[i, j]) if plot_convergence: - ax = fig.add_subplot(spec[ndims,:]) - skopt_plot_convergence(self._skopt_result,ax=ax) + ax = fig.add_subplot(spec[ndims, :]) + skopt_plot_convergence(self._skopt_result, ax=ax) spec.tight_layout(fig) @@ -277,14 +282,20 @@ def get_optimized_arguments(self): where the OptimizationParameter items have been replaced with the optimal values obtained from the optimizer """ - optimized_dict = {p.name: v for p,v in zip(self._parameter_list,self._skopt_result.x)} - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._init_args } + optimized_dict = { + p.name: v for p, v in zip(self._parameter_list, self._skopt_result.x) + } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._init_args + } init_opt = self._init_args | filtered_dict - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._affine_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._affine_args + } affine_opt = self._affine_args | filtered_dict - + affine_transform = partial(AffineTransform, **self._affine_static_args)( **affine_opt ) @@ -292,13 +303,17 @@ def get_optimized_arguments(self): affine_transform, init_opt["datacube"] ) init_opt["initial_scan_positions"] = scan_positions - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._preprocess_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._preprocess_args + } prep_opt = self._preprocess_args | filtered_dict - - filtered_dict = { k: v for k,v in optimized_dict.items() if k in self._reconstruction_args } + + filtered_dict = { + k: v for k, v in optimized_dict.items() if k in self._reconstruction_args + } reco_opt = self._reconstruction_args | filtered_dict - + return init_opt, prep_opt, reco_opt def _split_static_and_optimization_vars(self, argdict): @@ -387,10 +402,13 @@ def f(ptycho): return -np.std(np.angle(ptycho.object_cropped)) elif error_metric == "entropy-phase": + def f(ptycho): obj = np.angle(ptycho.object_cropped) - gx,gy = np.gradient(obj) - ghist,_,_ = np.histogram2d(gx.ravel(),gy.ravel(),bins=obj.shape,density=True) + gx, gy = np.gradient(obj) + ghist, _, _ = np.histogram2d( + gx.ravel(), gy.ravel(), bins=obj.shape, density=True + ) nz = ghist > 0 S = np.sum(ghist[nz] * np.log2(ghist[nz])) return S @@ -484,14 +502,14 @@ def f(**kwargs): def _set_optimizer_defaults( self, - verbose = False, - plot_center_of_mass = False, - plot_rotation = False, - plot_probe_overlaps = False, - progress_bar = False, - store_iterations = False, - reset = True, - ): + verbose=False, + plot_center_of_mass=False, + plot_rotation=False, + plot_probe_overlaps=False, + progress_bar=False, + store_iterations=False, + reset=True, + ): """ Set all of the verbose and plotting to False, allowing for user-overwrite. """ @@ -541,7 +559,6 @@ def __init__( if space not in ("real", "integer", "bool", "categorical"): raise ValueError(f"Unknown Parameter type: {space}") - scaling = scaling.lower() if scaling not in ("uniform", "log-uniform"): raise ValueError(f"Unknown scaling: {scaling}") From 455c19cdb549acc9f91f26465240dd60d6cffa6f Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:00:23 -0700 Subject: [PATCH 257/362] ptychoptimize imports ordering --- py4DSTEM/process/phase/parameter_optimize.py | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/py4DSTEM/process/phase/parameter_optimize.py b/py4DSTEM/process/phase/parameter_optimize.py index c8a51171d..125b72c71 100644 --- a/py4DSTEM/process/phase/parameter_optimize.py +++ b/py4DSTEM/process/phase/parameter_optimize.py @@ -1,22 +1,19 @@ -from tqdm import tqdm -from skopt import gp_minimize -from skopt.space import Real, Integer, Categorical -from skopt.plots import ( - plot_convergence as skopt_plot_convergence, - plot_gaussian_process as skopt_plot_gaussian_process, - plot_evaluations as skopt_plot_evaluations, - plot_objective as skopt_plot_objective, -) -from skopt.utils import use_named_args -import matplotlib.pyplot as plt -from matplotlib.gridspec import GridSpec -import numpy as np - from functools import partial -from typing import Union, Callable +from typing import Callable, Union +import matplotlib.pyplot as plt +import numpy as np +from matplotlib.gridspec import GridSpec from py4DSTEM.process.phase.iterative_base_class import PhaseReconstruction from py4DSTEM.process.phase.utils import AffineTransform +from skopt import gp_minimize +from skopt.plots import plot_convergence as skopt_plot_convergence +from skopt.plots import plot_evaluations as skopt_plot_evaluations +from skopt.plots import plot_gaussian_process as skopt_plot_gaussian_process +from skopt.plots import plot_objective as skopt_plot_objective +from skopt.space import Categorical, Integer, Real +from skopt.utils import use_named_args +from tqdm import tqdm class PtychographyOptimizer: From a78b67dbf2a43c52c247a6521ef7f8cc102ee990 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:03:57 -0700 Subject: [PATCH 258/362] init bugfix --- py4DSTEM/process/phase/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index ee542524f..cb9176375 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -10,6 +10,6 @@ from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction -from py4DSTEM.process.phase.utils import OptimizationParameter, PtychographyOptimizer +from py4DSTEM.process.phase.parameter_optimize import OptimizationParameter, PtychographyOptimizer # fmt: on From 47200eb0096cb4aa5486a40660321b02c1704da4 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:36:17 -0700 Subject: [PATCH 259/362] making generalized-projections ptychoptimize-compatible --- .../iterative_mixedstate_ptychography.py | 30 +++++++++++++---- .../iterative_multislice_ptychography.py | 32 +++++++++++++------ .../iterative_overlap_magnetic_tomography.py | 32 +++++++++++++------ .../phase/iterative_overlap_tomography.py | 32 +++++++++++++------ .../iterative_simultaneous_ptychography.py | 30 +++++++++++++---- .../iterative_singleslice_ptychography.py | 30 +++++++++++++---- 6 files changed, 138 insertions(+), 48 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 8d4574aa4..3450d1b13 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1259,6 +1259,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1303,7 +1306,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1311,6 +1314,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1390,17 +1399,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1459,7 +1474,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 36b44b77e..f9f8c2d29 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1653,6 +1653,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1703,7 +1706,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1711,8 +1714,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1804,17 +1811,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1873,7 +1886,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 9d4acfc4c..5d70b99ce 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1877,6 +1877,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1923,7 +1926,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1931,8 +1934,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -2010,17 +2017,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -2079,7 +2092,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 82d1caac3..037a3c805 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1690,6 +1690,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1733,7 +1736,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1741,8 +1744,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. - reconstruction_parameter: float, optional - Tuning parameter to interpolate b/w DM-AP and DM-RAAR + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1818,17 +1825,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1887,7 +1900,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 9e4b39cf5..629108b54 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2405,6 +2405,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -2453,7 +2456,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -2461,6 +2464,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -2549,17 +2558,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -2618,7 +2633,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 52aa2f816..d977dc916 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1167,6 +1167,9 @@ def reconstruct( max_iter: int = 64, reconstruction_method: str = "gradient-descent", reconstruction_parameter: float = 1.0, + reconstruction_parameter_a: float = None, + reconstruction_parameter_b: float = None, + reconstruction_parameter_c: float = None, max_batch_size: int = None, seed_random: int = None, step_size: float = 0.5, @@ -1211,7 +1214,7 @@ def reconstruct( Maximum number of iterations to run reconstruction_method: str, optional Specifies which reconstruction algorithm to use, one of: - "generalized-projection", + "generalized-projections", "DM_AP" (or "difference-map_alternating-projections"), "RAAR" (or "relaxed-averaged-alternating-reflections"), "RRR" (or "relax-reflect-reflect"), @@ -1219,6 +1222,12 @@ def reconstruct( "GD" (or "gradient_descent") reconstruction_parameter: float, optional Reconstruction parameter for various reconstruction methods above. + reconstruction_parameter_a: float, optional + Reconstruction parameter a for reconstruction_method='generalized-projections'. + reconstruction_parameter_b: float, optional + Reconstruction parameter b for reconstruction_method='generalized-projections'. + reconstruction_parameter_c: float, optional + Reconstruction parameter c for reconstruction_method='generalized-projections'. max_batch_size: int, optional Max number of probes to update at once seed_random: int, optional @@ -1301,17 +1310,23 @@ def reconstruct( # Reconstruction method - if reconstruction_method == "generalized-projection": - if np.array(reconstruction_parameter).shape != (3,): + if reconstruction_method == "generalized-projections": + if ( + reconstruction_parameter_a is None + or reconstruction_parameter_b is None + or reconstruction_parameter_c is None + ): raise ValueError( ( - "reconstruction_parameter must be a list of three numbers " - "when using `reconstriction_method`=generalized-projection." + "reconstruction_parameter_a/b/c must all be specified " + "when using reconstruction_method='generalized-projections'." ) ) use_projection_scheme = True - projection_a, projection_b, projection_c = reconstruction_parameter + projection_a = reconstruction_parameter_a + projection_b = reconstruction_parameter_b + projection_c = reconstruction_parameter_c step_size = None elif ( reconstruction_method == "DM_AP" @@ -1370,7 +1385,8 @@ def reconstruct( else: raise ValueError( ( - "reconstruction_method must be one of 'DM_AP' (or 'difference-map_alternating-projections'), " + "reconstruction_method must be one of 'generalized-projections', " + "'DM_AP' (or 'difference-map_alternating-projections'), " "'RAAR' (or 'relaxed-averaged-alternating-reflections'), " "'RRR' (or 'relax-reflect-reflect'), " "'SUPERFLIP' (or 'charge-flipping'), " From e4c0c325a2742d5e26359d06bfc7fec614006b74 Mon Sep 17 00:00:00 2001 From: gvarnavi Date: Fri, 7 Jul 2023 09:43:38 -0700 Subject: [PATCH 260/362] centered Fourier-probe extent --- .../phase/iterative_mixedstate_ptychography.py | 16 ++++++++-------- .../phase/iterative_multislice_ptychography.py | 17 ++++++++--------- .../phase/iterative_overlap_tomography.py | 17 ++++++++--------- .../iterative_simultaneous_ptychography.py | 8 ++++---- .../phase/iterative_singleslice_ptychography.py | 16 ++++++++-------- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 3450d1b13..d4e2e5346 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1838,10 +1838,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ @@ -2075,10 +2075,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index f9f8c2d29..d477da8ce 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -2269,12 +2269,11 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] - elif plot_probe: probe_extent = [ 0, @@ -2510,10 +2509,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 037a3c805..61d40473d 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2460,12 +2460,11 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] - elif plot_probe: probe_extent = [ 0, @@ -2717,10 +2716,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 629108b54..545900634 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -3052,10 +3052,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index d977dc916..791e3ffb5 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1751,10 +1751,10 @@ def _visualize_last_iteration( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ @@ -1988,10 +1988,10 @@ def _visualize_all_iterations( if plot_fourier_probe: probe_extent = [ - 0, - self.angular_sampling[1] * self._region_of_interest_shape[1], - self.angular_sampling[0] * self._region_of_interest_shape[0], - 0, + -self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[1] * self._region_of_interest_shape[1] / 2, + self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, + -self.angular_sampling[0] * self._region_of_interest_shape[0] / 2, ] elif plot_probe: probe_extent = [ From 4344eef22a9fcf8c7310a1b012888b329cffd0dd Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 7 Jul 2023 17:21:08 -0700 Subject: [PATCH 261/362] Force COM measured for DPC --- .../process/phase/iterative_base_class.py | 71 +++++++++++-------- py4DSTEM/process/phase/iterative_dpc.py | 24 +++++-- .../iterative_overlap_magnetic_tomography.py | 6 +- .../phase/iterative_overlap_tomography.py | 6 +- 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 766d03c6a..76583815e 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -281,7 +281,7 @@ def _extract_intensities_and_calibrations_from_datacube( # Copies intensities to device casting to float32 xp = self._xp - intensities = xp.asarray(datacube.data, dtype=xp.float32) + intensities = datacube.data self._grid_scan_shape = intensities.shape[:2] # Extracts calibrations @@ -414,6 +414,7 @@ def _calculate_intensities_center_of_mass( dp_mask: np.ndarray = None, fit_function: str = "plane", com_shifts: np.ndarray = None, + com_measured: np.ndarray = None, ): """ Common preprocessing function to compute and fit diffraction intensities CoM @@ -426,9 +427,10 @@ def _calculate_intensities_center_of_mass( If not None, apply mask to datacube amplitude fit_function: str, optional 2D fitting function for CoM fitting. One of 'plane','parabola','bezier_two' - com_shifts, np.ndarray, optional + com_shifts, tuple of ndarrays (CoMx measured, CoMy measured) If not None, com_shifts are fitted on the measured CoM values. - + com_measured: tuple of ndarrays (CoMx measured, CoMy measured) + If not None, com_measured are passed as com_measured_x, com_measured_y Returns ------- @@ -449,39 +451,48 @@ def _calculate_intensities_center_of_mass( xp = self._xp asnumpy = self._asnumpy - # Coordinates - kx = xp.arange(intensities.shape[-2], dtype=xp.float32) - ky = xp.arange(intensities.shape[-1], dtype=xp.float32) - kya, kxa = xp.meshgrid(ky, kx) + intensities = xp.asarray(intensities, dtype=xp.float32) + + # for ptycho + if com_measured: + com_measured_x, com_measured_y = com_measured - # calculate CoM - if dp_mask is not None: - if dp_mask.shape != intensities.shape[-2:]: - raise ValueError( - ( - f"Mask shape should be (Qx,Qy):{intensities.shape[-2:]}, " - f"not {dp_mask.shape}" - ) - ) - intensities_mask = intensities * xp.asarray(dp_mask, dtype=xp.float32) else: - intensities_mask = intensities + # Coordinates + kx = xp.arange(intensities.shape[-2], dtype=xp.float32) + ky = xp.arange(intensities.shape[-1], dtype=xp.float32) + kya, kxa = xp.meshgrid(ky, kx) - intensities_sum = xp.sum(intensities_mask, axis=(-2, -1)) - com_measured_x = ( - xp.sum(intensities_mask * kxa[None, None], axis=(-2, -1)) / intensities_sum - ) - com_measured_y = ( - xp.sum(intensities_mask * kya[None, None], axis=(-2, -1)) / intensities_sum - ) + # calculate CoM + if dp_mask is not None: + if dp_mask.shape != intensities.shape[-2:]: + raise ValueError( + ( + f"Mask shape should be (Qx,Qy):{intensities.shape[-2:]}, " + f"not {dp_mask.shape}" + ) + ) + intensities_mask = intensities * xp.asarray(dp_mask, dtype=xp.float32) + else: + intensities_mask = intensities + + intensities_sum = xp.sum(intensities_mask, axis=(-2, -1)) + com_measured_x = ( + xp.sum(intensities_mask * kxa[None, None], axis=(-2, -1)) + / intensities_sum + ) + com_measured_y = ( + xp.sum(intensities_mask * kya[None, None], axis=(-2, -1)) + / intensities_sum + ) - # Fit function to center of mass if com_shifts is None: com_shifts = fit_origin( (asnumpy(com_measured_x), asnumpy(com_measured_y)), fitfunction=fit_function, ) + # Fit function to center of mass com_fitted_x = xp.asarray(com_shifts[0], dtype=xp.float32) com_fitted_y = xp.asarray(com_shifts[1], dtype=xp.float32) @@ -993,8 +1004,8 @@ def _solve_for_center_of_mass_relative_rotation( cmap = kwargs.pop("cmap", "RdBu_r") extent = [ 0, - self._scan_sampling[1] * self._intensities.shape[1], - self._scan_sampling[0] * self._intensities.shape[0], + self._scan_sampling[1] * _com_measured_x.shape[1], + self._scan_sampling[0] * _com_measured_x.shape[0], 0, ] @@ -1031,8 +1042,8 @@ def _solve_for_center_of_mass_relative_rotation( extent = [ 0, - self._scan_sampling[1] * self._intensities.shape[1], - self._scan_sampling[0] * self._intensities.shape[0], + self._scan_sampling[1] * com_x.shape[1], + self._scan_sampling[0] * com_x.shape[0], 0, ] diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index e6f7659bd..4e890db79 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -4,7 +4,7 @@ """ import warnings -from typing import Tuple +from typing import Tuple, Union, Sequence import matplotlib.pyplot as plt import numpy as np @@ -239,7 +239,8 @@ def preprocess( fit_function: str = "plane", force_com_rotation: float = None, force_com_transpose: bool = None, - force_com_shifts: float = None, + force_com_shifts: Union[Sequence[np.ndarray], Sequence[float]] = None, + force_com_measured: Sequence[np.ndarray] = None, plot_center_of_mass: str = "default", plot_rotation: bool = True, **kwargs, @@ -270,6 +271,8 @@ def preprocess( Force whether diffraction intensities need to be transposed. force_com_shifts: tuple of ndarrays (CoMx, CoMy) Force CoM fitted shifts + force_com_measured: tuple of ndarrays (CoMx measured, CoMy measured) + Force CoM measured shifts plot_center_of_mass: str, optional If 'default', the corrected CoM arrays will be displayed If 'all', the computed and fitted CoM arrays will be displayed @@ -287,12 +290,18 @@ def preprocess( self._dp_mask = dp_mask if self._datacube is None: - raise ValueError( - ( - "The preprocess() method requires a DataCube. " - "Please run dpc.attach_datacube(DataCube) first." + if force_com_measured is None: + raise ValueError( + ( + "The preprocess() method requires either a DataCube " + "or `force_com_measured`. " + "Please run dpc.attach_datacube(DataCube) to attach DataCube." + ) + ) + else: + self._datacube = DataCube( + data=np.empty(force_com_measured[0].shape + (1, 1)) ) - ) self._intensities = self._extract_intensities_and_calibrations_from_datacube( self._datacube, @@ -311,6 +320,7 @@ def preprocess( dp_mask=self._dp_mask, fit_function=fit_function, com_shifts=force_com_shifts, + com_measured=force_com_measured, ) ( diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 5d70b99ce..939f42dec 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -2488,11 +2488,7 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - ( - self._object, - self._probe, - _, - ) = self._constraints( + (self._object, self._probe, _,) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 61d40473d..6b0a16e2e 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2212,11 +2212,7 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - ( - self._object, - self._probe, - _, - ) = self._constraints( + (self._object, self._probe, _,) = self._constraints( self._object, self._probe, None, From 783e8bb6a90e4436ad9741e7a4a25367dbd42eae Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 8 Jul 2023 07:00:14 -0700 Subject: [PATCH 262/362] bug fix --- py4DSTEM/process/phase/iterative_parallax.py | 1 + 1 file changed, 1 insertion(+) diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 5ab4c6cdd..576342631 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -171,6 +171,7 @@ def preprocess( self._datacube, require_calibrations=True, ) + self._intensities = xp.asarray(self._intensities, dtype=xp.float32) # make sure mean diffraction pattern is shaped correctly if (self._dp_mean.shape[0] != self._intensities.shape[2]) or ( From fd87c3d471f9d7bdba60d53a495f97395f1ce09c Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:04:59 -0700 Subject: [PATCH 263/362] Adding probe amplitude regularization --- py4DSTEM/process/phase/utils.py | 242 ++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index d57ad820a..8442b6cbc 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -3,6 +3,7 @@ import matplotlib.pyplot as plt import numpy as np import functools +from scipy.optimize import curve_fit try: import cupy as cp @@ -1274,3 +1275,244 @@ def nesterov_gamma(zero_indexed_iter_num): return (1 - nesterov_lambda(one_indexed_iter_num)) / nesterov_lambda( one_indexed_iter_num + 1 ) + + + + + + +def regularize_probe_amp( + probe_init, + width_max_pixels = 2.0, + plot_polar = False, + plot_result = False, + figsize = (5,5), + ): + """ + Assume that the probe is centered in Fourier space. Note that I re-implemented the polar/cartesian transforms here for portability. + """ + + # Get probe intensity + probe_amp = np.abs(probe_init) + probe_int = probe_amp**2 + + # coordinates + xa,ya = np.meshgrid( + np.arange(probe_init.shape[0]), + np.arange(probe_init.shape[1]), + indexing = 'ij', + ) + + # Center of mass for probe intensity + int_total = np.sum(probe_int) + xy_center = ( + np.sum(probe_int * xa) / int_total, + np.sum(probe_int * ya) / int_total, + ) + + # Convert intensity to polar coordinates + polar_int = im_cart_to_polar( + probe_int, + xy_center = xy_center, + ) + + # Fit corrected probe intensity + radius = np.arange(polar_int.shape[1]) + + # estimate initial parameters + sub = polar_int > (np.max(polar_int)*0.5) + sig_0 = np.mean(polar_int[sub]) + rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) + width = np.minimum(1.0, width_max_pixels) + + # init + coefs_all = np.zeros((polar_int.shape[0],3)) + coefs_all[:,0] = sig_0 + coefs_all[:,1] = rad_0 + coefs_all[:,2] = width + + # bounds + lb = (0, 0, 0.5) + ub = (np.inf, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_fit = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_fit[a0,:] = step_model( + radius, + coefs_all[a0,:]) + + # Compute best-fit constant intensity inside probe + sig_0 = np.median(coefs_all[:,0]) + coefs_all[:,0] = sig_0 + lb = (sig_0-1e-8, 0, 0.5) + ub = (sig_0+1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_int_corr[a0,:] = step_model( + radius, + coefs_all[a0,:]) + + # Convert back to cartesian coordinates + int_corr = im_polar_to_cart( + polar_int_corr, + xy_size = probe_init.shape, + xy_center = xy_center, + ) + + # Assemble output probe + probe_corr = np.sqrt(np.maximum(int_corr,0)) \ + * np.exp(1j*np.angle(probe_init)) + + # plotting + if plot_result: + fig,ax = plt.subplots(figsize = (figsize[0]*2, figsize[1])) + ax.imshow( + np.hstack(( + probe_int, + int_corr, + )), + cmap = 'turbo', + ) + if plot_polar: + fig,ax = plt.subplots(figsize = figsize) + ax.imshow( + np.hstack(( + polar_int, + polar_fit, + polar_int_corr, + )), + cmap = 'turbo', + ) + + return probe_corr + + +def step_model(radius, *coefs): + coefs = np.squeeze(np.array(coefs)) + + sig_0 = coefs[0] + rad_0 = coefs[1] + width = coefs[2] + + return sig_0 * np.clip((rad_0 - radius) / width, 0, 1) + + +def im_cart_to_polar( + im_cart, + xy_center, + num_theta_bins = 180, + radius_max = None, + ): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + xa,ya = np.meshgrid( + np.arange(im_cart.shape[0]), + np.arange(im_cart.shape[1]), + indexing = 'ij', + ) + if radius_max is None: + radius_max = np.ceil(np.sqrt(np.sum( + np.array(im_cart.shape).astype('float')**2 + )) / 2.0).astype('int') + r = np.arange(radius_max) + t = np.linspace( + 0, + 2.0*np.pi, + num_theta_bins, + endpoint = False, + ) + ra,ta = np.meshgrid(r,t) + + # resampling coordinates + x = (ra * np.cos(ta) + xy_center[0]) + y = (ra * np.sin(ta) + xy_center[1]) + xf = np.floor(x).astype('int') + yf = np.floor(y).astype('int') + dx = x - xf + dy = y - yf + + # resample image + im_polar = \ + im_cart.ravel()[np.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode='clip', + )] * (1-dx) * (1-dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf+1, yf), + im_cart.shape, + mode='clip', + )] * ( dx) * (1-dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf, yf+1), + im_cart.shape, + mode='clip', + )] * (1-dx) * ( dy) + \ + im_cart.ravel()[np.ravel_multi_index( + (xf+1, yf+1), + im_cart.shape, + mode='clip', + )] * ( dx) * ( dy) + + return im_polar + + +def im_polar_to_cart( + im_polar, + xy_size, + xy_center, + ): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + xa,ya = np.meshgrid( + np.arange(xy_size[0]) - xy_center[0], + np.arange(xy_size[1]) - xy_center[1], + indexing = 'ij', + ) + ra = np.sqrt(xa**2 + ya**2) + ta = np.arctan2(ya,xa) + t = np.linspace(0,2*np.pi,im_polar.shape[0],endpoint = False) + t_step = t[1] - t[0] + + # resampling coordinates + t_ind = ta / t_step + r_ind = ra.copy() + tf = np.floor(t_ind).astype('int') + rf = np.floor(r_ind).astype('int') + dt = t_ind - tf + dr = r_ind - rf + + # resample image + im_cart = im_polar.ravel()[np.ravel_multi_index( + (np.mod(tf, im_polar.shape[0]), rf), + im_polar.shape, + mode='clip', + )] + + return im_cart + From d33b62693220ba9c7bcd185c67ee53a39514e6ea Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:08:45 -0700 Subject: [PATCH 264/362] Adding docstrings --- py4DSTEM/process/phase/utils.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 8442b6cbc..112b1242c 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1284,12 +1284,40 @@ def nesterov_gamma(zero_indexed_iter_num): def regularize_probe_amp( probe_init, width_max_pixels = 2.0, - plot_polar = False, plot_result = False, + plot_polar = False, + cmap = 'turbo', figsize = (5,5), ): """ - Assume that the probe is centered in Fourier space. Note that I re-implemented the polar/cartesian transforms here for portability. + Assume that the probe is centered in Fourier space. Note we + re-implemented the polar/cartesian transforms here for portability. + + Parameters + -------- + probe_init: np.array + 2D complex image of the probe in Fourier space. + width_max_pixels: float + Maximum edge width of the probe in pixels. + plot_result: bool + Plot the input and output probes. + plot_polar: bool + Plot the polar transformed images: + 1 - initial probe + 2 - best fit of step model for each line + 3 - best fit enforcing constant intensity inside aperture + cmap: string + colormap of the plots. + figsize: tuple + size of the output figures. + (will be doubled along horizontal axis for cartesian images) + + Returns + -------- + probe_corr: np.array + 2D complex image of the corrected probe in Fourier space. + + """ # Get probe intensity From c62d3e4ab9c5a0c6cf7c33d80f0797db3b20ab8f Mon Sep 17 00:00:00 2001 From: cophus Date: Sun, 9 Jul 2023 19:23:55 -0700 Subject: [PATCH 265/362] adding more options, cleaning up --- py4DSTEM/process/phase/utils.py | 64 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 112b1242c..29b76165c 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1284,6 +1284,8 @@ def nesterov_gamma(zero_indexed_iter_num): def regularize_probe_amp( probe_init, width_max_pixels = 2.0, + enforce_constant_intensity = True, + return_coefs = False, plot_result = False, plot_polar = False, cmap = 'turbo', @@ -1299,6 +1301,10 @@ def regularize_probe_amp( 2D complex image of the probe in Fourier space. width_max_pixels: float Maximum edge width of the probe in pixels. + enforce_constant_intensity: bool + Set to true to make intensity inside the aperture constant. + return_coefs: bool + If true, fitting coefficients will also be returned. plot_result: bool Plot the input and output probes. plot_polar: bool @@ -1316,6 +1322,9 @@ def regularize_probe_amp( -------- probe_corr: np.array 2D complex image of the corrected probe in Fourier space. + coefs_all: np.array (optional) + coefficients for the + """ @@ -1323,7 +1332,7 @@ def regularize_probe_amp( # Get probe intensity probe_amp = np.abs(probe_init) probe_int = probe_amp**2 - + # coordinates xa,ya = np.meshgrid( np.arange(probe_init.shape[0]), @@ -1351,7 +1360,7 @@ def regularize_probe_amp( sub = polar_int > (np.max(polar_int)*0.5) sig_0 = np.mean(polar_int[sub]) rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) - width = np.minimum(1.0, width_max_pixels) + width = width_max_pixels * 0.5 # init coefs_all = np.zeros((polar_int.shape[0],3)) @@ -1360,7 +1369,7 @@ def regularize_probe_amp( coefs_all[:,2] = width # bounds - lb = (0, 0, 0.5) + lb = (0.0, 0.0, 1e-4) ub = (np.inf, np.inf, width_max_pixels) # refine parameters, generate polar image @@ -1378,26 +1387,30 @@ def regularize_probe_amp( radius, coefs_all[a0,:]) - # Compute best-fit constant intensity inside probe - sig_0 = np.median(coefs_all[:,0]) - coefs_all[:,0] = sig_0 - lb = (sig_0-1e-8, 0, 0.5) - ub = (sig_0+1e-8, np.inf, width_max_pixels) + if enforce_constant_intensity: + # Compute best-fit constant intensity inside probe, update bounds + sig_0 = np.median(coefs_all[:,0]) + coefs_all[:,0] = sig_0 + lb = (sig_0-1e-8, 0.0, 1e-4) + ub = (sig_0+1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0,:] = curve_fit( + step_model, + radius, + polar_int[a0,:], + p0 = coefs_all[a0,:], + xtol = 1e-12, + bounds = (lb,ub), + )[0] + polar_int_corr[a0,:] = step_model( + radius, + coefs_all[a0,:]) - # refine parameters, generate polar image - polar_int_corr = np.zeros_like(polar_int) - for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_int_corr[a0,:] = step_model( - radius, - coefs_all[a0,:]) + else: + polar_int_corr = polar_fit # Convert back to cartesian coordinates int_corr = im_polar_to_cart( @@ -1431,7 +1444,10 @@ def regularize_probe_amp( cmap = 'turbo', ) - return probe_corr + if return_coefs: + return probe_corr, coefs_all + else: + return probe_corr def step_model(radius, *coefs): @@ -1441,7 +1457,7 @@ def step_model(radius, *coefs): rad_0 = coefs[1] width = coefs[2] - return sig_0 * np.clip((rad_0 - radius) / width, 0, 1) + return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) def im_cart_to_polar( From a7ee689ed67d67bf153be45923aacbe0cf6e6206 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Sun, 9 Jul 2023 21:44:02 -0700 Subject: [PATCH 266/362] updated Colins code to work with corner-centered probes. will clean up and port to constraints tomorrow morning. --- py4DSTEM/process/phase/utils.py | 283 ++++++++++++++++---------------- 1 file changed, 140 insertions(+), 143 deletions(-) diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 29b76165c..c92f0d38b 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -14,6 +14,7 @@ from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom +from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter # fmt: off @@ -1277,24 +1278,20 @@ def nesterov_gamma(zero_indexed_iter_num): ) - - - - def regularize_probe_amp( probe_init, - width_max_pixels = 2.0, - enforce_constant_intensity = True, - return_coefs = False, - plot_result = False, - plot_polar = False, - cmap = 'turbo', - figsize = (5,5), - ): + width_max_pixels=2.0, + enforce_constant_intensity=True, + return_coefs=False, + plot_result=False, + plot_polar=False, + cmap="turbo", + figsize=(5, 5), +): """ - Assume that the probe is centered in Fourier space. Note we + Assumes the probe is corner-centered in Fourier space. Note we re-implemented the polar/cartesian transforms here for portability. - + Parameters -------- probe_init: np.array @@ -1323,50 +1320,36 @@ def regularize_probe_amp( probe_corr: np.array 2D complex image of the corrected probe in Fourier space. coefs_all: np.array (optional) - coefficients for the - - - + coefficients for the """ # Get probe intensity probe_amp = np.abs(probe_init) probe_int = probe_amp**2 - # coordinates - xa,ya = np.meshgrid( - np.arange(probe_init.shape[0]), - np.arange(probe_init.shape[1]), - indexing = 'ij', - ) - # Center of mass for probe intensity - int_total = np.sum(probe_int) - xy_center = ( - np.sum(probe_int * xa) / int_total, - np.sum(probe_int * ya) / int_total, - ) + xy_center = get_CoM(probe_int, device="cpu", corner_centered=True) # Convert intensity to polar coordinates - polar_int = im_cart_to_polar( + polar_int = cartesian_to_polar_transform_2Ddata( probe_int, - xy_center = xy_center, - ) + xy_center=xy_center, + ) # Fit corrected probe intensity radius = np.arange(polar_int.shape[1]) # estimate initial parameters - sub = polar_int > (np.max(polar_int)*0.5) + sub = polar_int > (np.max(polar_int) * 0.5) sig_0 = np.mean(polar_int[sub]) - rad_0 = np.max(np.argwhere(np.sum(sub,axis=0))) + rad_0 = np.max(np.argwhere(np.sum(sub, axis=0))) width = width_max_pixels * 0.5 # init - coefs_all = np.zeros((polar_int.shape[0],3)) - coefs_all[:,0] = sig_0 - coefs_all[:,1] = rad_0 - coefs_all[:,2] = width + coefs_all = np.zeros((polar_int.shape[0], 3)) + coefs_all[:, 0] = sig_0 + coefs_all[:, 1] = rad_0 + coefs_all[:, 2] = width # bounds lb = (0.0, 0.0, 1e-4) @@ -1375,80 +1358,79 @@ def regularize_probe_amp( # refine parameters, generate polar image polar_fit = np.zeros_like(polar_int) for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_fit[a0,:] = step_model( + coefs_all[a0, :] = curve_fit( + step_model, radius, - coefs_all[a0,:]) + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_fit[a0, :] = step_model(radius, coefs_all[a0, :]) if enforce_constant_intensity: # Compute best-fit constant intensity inside probe, update bounds - sig_0 = np.median(coefs_all[:,0]) - coefs_all[:,0] = sig_0 - lb = (sig_0-1e-8, 0.0, 1e-4) - ub = (sig_0+1e-8, np.inf, width_max_pixels) + sig_0 = np.median(coefs_all[:, 0]) + coefs_all[:, 0] = sig_0 + lb = (sig_0 - 1e-8, 0.0, 1e-4) + ub = (sig_0 + 1e-8, np.inf, width_max_pixels) # refine parameters, generate polar image polar_int_corr = np.zeros_like(polar_int) for a0 in range(polar_int.shape[0]): - coefs_all[a0,:] = curve_fit( - step_model, - radius, - polar_int[a0,:], - p0 = coefs_all[a0,:], - xtol = 1e-12, - bounds = (lb,ub), - )[0] - polar_int_corr[a0,:] = step_model( + coefs_all[a0, :] = curve_fit( + step_model, radius, - coefs_all[a0,:]) + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_int_corr[a0, :] = step_model(radius, coefs_all[a0, :]) else: polar_int_corr = polar_fit # Convert back to cartesian coordinates - int_corr = im_polar_to_cart( + int_corr = polar_to_cartesian_transform_2Ddata( polar_int_corr, - xy_size = probe_init.shape, - xy_center = xy_center, - ) + xy_size=probe_init.shape, + xy_center=xy_center, + ) # Assemble output probe - probe_corr = np.sqrt(np.maximum(int_corr,0)) \ - * np.exp(1j*np.angle(probe_init)) + probe_corr = np.sqrt(np.maximum(int_corr, 0)) * np.exp(1j * np.angle(probe_init)) # plotting if plot_result: - fig,ax = plt.subplots(figsize = (figsize[0]*2, figsize[1])) + fig, ax = plt.subplots(figsize=(figsize[0] * 2, figsize[1])) ax.imshow( - np.hstack(( - probe_int, - int_corr, - )), - cmap = 'turbo', - ) + np.hstack( + ( + np.fft.fftshift(probe_int), + np.fft.fftshift(int_corr), + ) + ), + cmap="turbo", + ) if plot_polar: - fig,ax = plt.subplots(figsize = figsize) + fig, ax = plt.subplots(figsize=figsize) ax.imshow( - np.hstack(( - polar_int, - polar_fit, - polar_int_corr, - )), - cmap = 'turbo', - ) + np.hstack( + ( + polar_int, + polar_fit, + polar_int_corr, + ) + ), + cmap="turbo", + ) if return_coefs: return probe_corr, coefs_all else: return probe_corr - + def step_model(radius, *coefs): coefs = np.squeeze(np.array(coefs)) @@ -1460,103 +1442,118 @@ def step_model(radius, *coefs): return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) -def im_cart_to_polar( +def cartesian_to_polar_transform_2Ddata( im_cart, xy_center, - num_theta_bins = 180, - radius_max = None, - ): + num_theta_bins=180, + radius_max=None, +): """ Quick cartesian to polar conversion. """ # coordinates - xa,ya = np.meshgrid( - np.arange(im_cart.shape[0]), - np.arange(im_cart.shape[1]), - indexing = 'ij', - ) if radius_max is None: - radius_max = np.ceil(np.sqrt(np.sum( - np.array(im_cart.shape).astype('float')**2 - )) / 2.0).astype('int') + radius_max = np.min(np.array(im_cart.shape) // 2) + r = np.arange(radius_max) t = np.linspace( 0, - 2.0*np.pi, + 2.0 * np.pi, num_theta_bins, - endpoint = False, - ) - ra,ta = np.meshgrid(r,t) + endpoint=False, + ) + ra, ta = np.meshgrid(r, t) # resampling coordinates - x = (ra * np.cos(ta) + xy_center[0]) - y = (ra * np.sin(ta) + xy_center[1]) - xf = np.floor(x).astype('int') - yf = np.floor(y).astype('int') + x = ra * np.cos(ta) + xy_center[0] + y = ra * np.sin(ta) + xy_center[1] + + xf = np.floor(x).astype("int") + yf = np.floor(y).astype("int") dx = x - xf dy = y - yf # resample image - im_polar = \ - im_cart.ravel()[np.ravel_multi_index( - (xf, yf), - im_cart.shape, - mode='clip', - )] * (1-dx) * (1-dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf+1, yf), - im_cart.shape, - mode='clip', - )] * ( dx) * (1-dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf, yf+1), - im_cart.shape, - mode='clip', - )] * (1-dx) * ( dy) + \ - im_cart.ravel()[np.ravel_multi_index( - (xf+1, yf+1), - im_cart.shape, - mode='clip', - )] * ( dx) * ( dy) + im_polar = ( + im_cart.ravel()[ + np.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode="wrap", + ) + ] + * (1 - dx) + * (1 - dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf + 1, yf), + im_cart.shape, + mode="wrap", + ) + ] + * (dx) + * (1 - dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf, yf + 1), + im_cart.shape, + mode="wrap", + ) + ] + * (1 - dx) + * (dy) + + im_cart.ravel()[ + np.ravel_multi_index( + (xf + 1, yf + 1), + im_cart.shape, + mode="wrap", + ) + ] + * (dx) + * (dy) + ) return im_polar -def im_polar_to_cart( +def polar_to_cartesian_transform_2Ddata( im_polar, xy_size, xy_center, - ): +): """ Quick cartesian to polar conversion. """ # coordinates - xa,ya = np.meshgrid( - np.arange(xy_size[0]) - xy_center[0], - np.arange(xy_size[1]) - xy_center[1], - indexing = 'ij', - ) - ra = np.sqrt(xa**2 + ya**2) - ta = np.arctan2(ya,xa) - t = np.linspace(0,2*np.pi,im_polar.shape[0],endpoint = False) + sx, sy = xy_size + cx, cy = xy_center + + x = np.fft.fftfreq(sx, d=1 / sx) + y = np.fft.fftfreq(sy, d=1 / sy) + xa, ya = np.meshgrid(x, y, indexing="ij") + ra = np.hypot(xa - cx, ya - cy) + ta = np.arctan2(ya, xa) + + t = np.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) t_step = t[1] - t[0] # resampling coordinates t_ind = ta / t_step r_ind = ra.copy() - tf = np.floor(t_ind).astype('int') - rf = np.floor(r_ind).astype('int') + tf = np.floor(t_ind).astype("int") + rf = np.floor(r_ind).astype("int") dt = t_ind - tf dr = r_ind - rf # resample image - im_cart = im_polar.ravel()[np.ravel_multi_index( - (np.mod(tf, im_polar.shape[0]), rf), + im_cart = im_polar.ravel()[ + np.ravel_multi_index( + (tf, rf), im_polar.shape, - mode='clip', - )] + mode=("wrap", "clip"), + ) + ] return im_cart - From c4f4b26425adb3501c1ee37ed2c4a0a2ee8046e9 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Mon, 10 Jul 2023 20:23:35 -0700 Subject: [PATCH 267/362] adding probe aperture constraint, aberration fitting. Only changed single-slice, will do rest of the classes tomorrow. --- .../iterative_ptychographic_constraints.py | 121 ++--- .../iterative_singleslice_ptychography.py | 105 +++-- py4DSTEM/process/phase/utils.py | 415 ++++++++++-------- 3 files changed, 304 insertions(+), 337 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 274e86f39..d3c5b34a9 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -3,6 +3,8 @@ array_slice, estimate_global_transformation_ransac, fft_shift, + regularize_probe_amplitude, + fit_aberration_surface, ) from py4DSTEM.process.utils import get_CoM @@ -338,67 +340,6 @@ def _probe_center_of_mass_constraint(self, current_probe): return shifted_probe - def _probe_radial_symmetrization_constraint_base( - self, - current_probe, - num_bins=None, - center=None, - ): - xp = self._xp - - sx, sy = current_probe.shape - - if center is None: - center = (0, 0) - - if num_bins is None: - num_bins = np.maximum(sx, sy) * 2 + 1 - - cx, cy = center - X = xp.fft.fftfreq(sx, d=1 / sx)[:, None] - Y = xp.fft.fftfreq(sy, d=1 / sy)[None] - r = xp.hypot(X - cx, Y - cy) - - rbin = (num_bins * r / r.max()).astype("int") - num = xp.bincount(rbin.ravel(), current_probe.ravel()) - denom = xp.bincount(rbin.ravel()) - denom[denom == 0] = 1 - - radial_mean = num / denom - - for r_bin, r_mean in enumerate(radial_mean): - if r_bin != 0.0: - current_probe[np.where(rbin == r_bin)] = r_mean - - return current_probe - - def _probe_radial_symmetrization_constraint( - self, - current_probe, - num_bins=None, - center=None, - ): - xp = self._xp - - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) - fourier_probe = xp.fft.fft2(current_probe) - - fourier_probe_real = fourier_probe.real.copy() - fourier_probe_imag = fourier_probe.imag.copy() - - fourier_probe_real = self._probe_radial_symmetrization_constraint_base( - fourier_probe_real, num_bins, center - ) - fourier_probe_imag = self._probe_radial_symmetrization_constraint_base( - fourier_probe_imag, num_bins, center - ) - - fourier_probe = fourier_probe_real + 1.0j * fourier_probe_imag - current_probe = xp.fft.ifft2(fourier_probe) - current_probe *= xp.sqrt(current_probe_sum / np.sum(np.abs(current_probe) ** 2)) - - return current_probe - def _probe_amplitude_constraint( self, current_probe, relative_radius, relative_width ): @@ -439,7 +380,10 @@ def _probe_amplitude_constraint( return updated_probe * normalization def _probe_fourier_amplitude_constraint( - self, current_probe, threshold, relative_width + self, + current_probe, + width_max_pixels, + enforce_constant_intensity, ): """ Ptychographic top-hat filtering of Fourier probe. @@ -460,27 +404,20 @@ def _probe_fourier_amplitude_constraint( Constrained probe estimate """ xp = self._xp - erf = self._erf + asnumpy = self._asnumpy current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft = xp.fft.fft2(current_probe) - current_probe_fft_amp = xp.abs(current_probe_fft) - threshold_px = xp.argmax( - current_probe_fft_amp < xp.max(current_probe_fft_amp) * threshold + updated_probe_fft, _, _, _ = regularize_probe_amplitude( + asnumpy(current_probe_fft), + width_max_pixels=width_max_pixels, + enforce_constant_intensity=enforce_constant_intensity, + corner_centered=True, ) - if threshold_px == 0: - return current_probe - - qx = xp.fft.fftfreq(current_probe.shape[0], 1) - qy = xp.fft.fftfreq(current_probe.shape[1], 1) - qya, qxa = xp.meshgrid(qy, qx) - qra = xp.sqrt(qxa**2 + qya**2) - threshold_px / current_probe.shape[0] - - sigma = np.sqrt(np.pi) / relative_width - tophat_mask = 0.5 * (1 - erf(sigma * qra / (1 - qra**2))) - updated_probe = xp.fft.ifft2(current_probe_fft * tophat_mask) + updated_probe_fft = xp.asarray(updated_probe_fft) + updated_probe = xp.fft.ifft2(updated_probe_fft) updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) normalization = xp.sqrt(current_probe_sum / updated_probe_sum) @@ -517,11 +454,11 @@ def _probe_aperture_constraint( return updated_probe * normalization - def _probe_residual_aberration_filtering_constraint( + def _probe_aberration_fitting_constraint( self, current_probe, - gaussian_filter_sigma, - fix_amplitude, + max_angular_order, + max_radial_order, ): """ Ptychographic probe smoothing constraint. @@ -543,24 +480,20 @@ def _probe_residual_aberration_filtering_constraint( """ xp = self._xp - gaussian_filter = self._gaussian_filter - known_aberrations_array = self._known_aberrations_array - gaussian_filter_sigma /= self._reciprocal_sampling[0] fourier_probe = xp.fft.fft2(current_probe) - if fix_amplitude: - fourier_probe_abs = xp.abs(fourier_probe) - - fourier_probe *= xp.conjugate(known_aberrations_array) - fourier_probe = gaussian_filter( - fourier_probe, gaussian_filter_sigma, mode="wrap" + fourier_probe_abs = xp.abs(fourier_probe) + sampling = self.sampling + + fitted_angle = fit_aberration_surface( + fourier_probe, + sampling, + max_angular_order, + max_radial_order, + xp=xp, ) - fourier_probe *= known_aberrations_array - - if fix_amplitude: - fourier_probe_angle = xp.angle(fourier_probe) - fourier_probe = fourier_probe_abs * xp.exp(1.0j * fourier_probe_angle) + fourier_probe = fourier_probe_abs * xp.exp(1.0j * fitted_angle) current_probe = xp.fft.ifft2(fourier_probe) return current_probe diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 791e3ffb5..bd7d57d68 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1000,15 +1000,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1038,14 +1038,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1053,10 +1051,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1122,31 +1121,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1179,20 +1176,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1246,19 +1243,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1593,12 +1589,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -1606,7 +1596,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index c92f0d38b..7f5287b3b 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -16,6 +16,7 @@ from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter +from skimage.restoration import unwrap_phase # fmt: off @@ -1278,19 +1279,143 @@ def nesterov_gamma(zero_indexed_iter_num): ) -def regularize_probe_amp( +def cartesian_to_polar_transform_2Ddata( + im_cart, + xy_center, + num_theta_bins=180, + radius_max=None, + corner_centered=False, + xp=np, +): + """ + Quick cartesian to polar conversion. + """ + + # coordinates + if radius_max is None: + if corner_centered: + radius_max = np.min(np.array(im_cart.shape) // 2) + else: + radius_max = np.sqrt(np.sum(np.array(im_cart.shape) ** 2)) // 2 + + r = xp.arange(radius_max) + t = xp.linspace( + 0, + 2.0 * np.pi, + num_theta_bins, + endpoint=False, + ) + ra, ta = xp.meshgrid(r, t) + + # resampling coordinates + x = ra * xp.cos(ta) + xy_center[0] + y = ra * xp.sin(ta) + xy_center[1] + + xf = xp.floor(x).astype("int") + yf = xp.floor(y).astype("int") + dx = x - xf + dy = y - yf + + mode = "wrap" if corner_centered else "clip" + + # resample image + im_polar = ( + im_cart.ravel()[ + xp.ravel_multi_index( + (xf, yf), + im_cart.shape, + mode=mode, + ) + ] + * (1 - dx) + * (1 - dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf + 1, yf), + im_cart.shape, + mode=mode, + ) + ] + * (dx) + * (1 - dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf, yf + 1), + im_cart.shape, + mode=mode, + ) + ] + * (1 - dx) + * (dy) + + im_cart.ravel()[ + xp.ravel_multi_index( + (xf + 1, yf + 1), + im_cart.shape, + mode=mode, + ) + ] + * (dx) + * (dy) + ) + + return im_polar + + +def polar_to_cartesian_transform_2Ddata( + im_polar, + xy_size, + xy_center, + corner_centered=False, + xp=np, +): + """ + Quick polar to cartesian conversion. + """ + + # coordinates + sx, sy = xy_size + cx, cy = xy_center + + if corner_centered: + x = xp.fft.fftfreq(sx, d=1 / sx) + y = xp.fft.fftfreq(sy, d=1 / sy) + else: + x = xp.arange(sx) + y = xp.arange(sy) + + xa, ya = xp.meshgrid(x, y, indexing="ij") + ra = xp.hypot(xa - cx, ya - cy) + ta = xp.arctan2(ya - cy, xa - cx) + + t = xp.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) + t_step = t[1] - t[0] + + # resampling coordinates + t_ind = ta / t_step + r_ind = ra.copy() + tf = xp.floor(t_ind).astype("int") + rf = xp.floor(r_ind).astype("int") + + # resample image + im_cart = im_polar.ravel()[ + xp.ravel_multi_index( + (tf, rf), + im_polar.shape, + mode=("wrap", "clip"), + ) + ] + + return im_cart + + +def regularize_probe_amplitude( probe_init, width_max_pixels=2.0, enforce_constant_intensity=True, - return_coefs=False, - plot_result=False, - plot_polar=False, - cmap="turbo", - figsize=(5, 5), + corner_centered=False, ): """ - Assumes the probe is corner-centered in Fourier space. Note we - re-implemented the polar/cartesian transforms here for portability. + Fits sigmoid for each angular direction. Parameters -------- @@ -1300,40 +1425,31 @@ def regularize_probe_amp( Maximum edge width of the probe in pixels. enforce_constant_intensity: bool Set to true to make intensity inside the aperture constant. - return_coefs: bool - If true, fitting coefficients will also be returned. - plot_result: bool - Plot the input and output probes. - plot_polar: bool - Plot the polar transformed images: - 1 - initial probe - 2 - best fit of step model for each line - 3 - best fit enforcing constant intensity inside aperture - cmap: string - colormap of the plots. - figsize: tuple - size of the output figures. - (will be doubled along horizontal axis for cartesian images) + corner_centered: bool + If True, the probe is assumed to be corner-centered Returns -------- - probe_corr: np.array + probe_corr: np.ndarray 2D complex image of the corrected probe in Fourier space. - coefs_all: np.array (optional) - coefficients for the + coefs_all: np.ndarray + coefficients for the sigmoid fits """ # Get probe intensity probe_amp = np.abs(probe_init) + probe_angle = np.angle(probe_init) probe_int = probe_amp**2 # Center of mass for probe intensity - xy_center = get_CoM(probe_int, device="cpu", corner_centered=True) + xy_center = get_CoM(probe_int, device="cpu", corner_centered=corner_centered) # Convert intensity to polar coordinates polar_int = cartesian_to_polar_transform_2Ddata( probe_int, xy_center=xy_center, + corner_centered=corner_centered, + xp=np, ) # Fit corrected probe intensity @@ -1346,6 +1462,9 @@ def regularize_probe_amp( width = width_max_pixels * 0.5 # init + def step_model(radius, sig_0, rad_0, width): + return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) + coefs_all = np.zeros((polar_int.shape[0], 3)) coefs_all[:, 0] = sig_0 coefs_all[:, 1] = rad_0 @@ -1366,194 +1485,114 @@ def regularize_probe_amp( xtol=1e-12, bounds=(lb, ub), )[0] - polar_fit[a0, :] = step_model(radius, coefs_all[a0, :]) - - if enforce_constant_intensity: - # Compute best-fit constant intensity inside probe, update bounds - sig_0 = np.median(coefs_all[:, 0]) - coefs_all[:, 0] = sig_0 - lb = (sig_0 - 1e-8, 0.0, 1e-4) - ub = (sig_0 + 1e-8, np.inf, width_max_pixels) - - # refine parameters, generate polar image - polar_int_corr = np.zeros_like(polar_int) - for a0 in range(polar_int.shape[0]): - coefs_all[a0, :] = curve_fit( - step_model, - radius, - polar_int[a0, :], - p0=coefs_all[a0, :], - xtol=1e-12, - bounds=(lb, ub), - )[0] - polar_int_corr[a0, :] = step_model(radius, coefs_all[a0, :]) + polar_fit[a0, :] = step_model(radius, *coefs_all[a0, :]) - else: - polar_int_corr = polar_fit + # Compute best-fit constant intensity inside probe, update bounds + sig_0 = np.median(coefs_all[:, 0]) + coefs_all[:, 0] = sig_0 + lb = (sig_0 - 1e-8, 0.0, 1e-4) + ub = (sig_0 + 1e-8, np.inf, width_max_pixels) + + # refine parameters, generate polar image + polar_int_corr = np.zeros_like(polar_int) + for a0 in range(polar_int.shape[0]): + coefs_all[a0, :] = curve_fit( + step_model, + radius, + polar_int[a0, :], + p0=coefs_all[a0, :], + xtol=1e-12, + bounds=(lb, ub), + )[0] + polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) # Convert back to cartesian coordinates int_corr = polar_to_cartesian_transform_2Ddata( polar_int_corr, xy_size=probe_init.shape, xy_center=xy_center, + corner_centered=corner_centered, ) - # Assemble output probe - probe_corr = np.sqrt(np.maximum(int_corr, 0)) * np.exp(1j * np.angle(probe_init)) - - # plotting - if plot_result: - fig, ax = plt.subplots(figsize=(figsize[0] * 2, figsize[1])) - ax.imshow( - np.hstack( - ( - np.fft.fftshift(probe_int), - np.fft.fftshift(int_corr), - ) - ), - cmap="turbo", - ) - if plot_polar: - fig, ax = plt.subplots(figsize=figsize) - ax.imshow( - np.hstack( - ( - polar_int, - polar_fit, - polar_int_corr, - ) - ), - cmap="turbo", - ) - - if return_coefs: - return probe_corr, coefs_all - else: - return probe_corr - + amp_corr = np.sqrt(np.maximum(int_corr, 0)) -def step_model(radius, *coefs): - coefs = np.squeeze(np.array(coefs)) + # Assemble output probe + if not enforce_constant_intensity: + max_coeff = np.sqrt(coefs_all[:, 0]).max() + amp_corr = amp_corr / max_coeff * probe_amp - sig_0 = coefs[0] - rad_0 = coefs[1] - width = coefs[2] + probe_corr = amp_corr * np.exp(1j * probe_angle) - return sig_0 * np.clip((rad_0 - radius) / width, 0.0, 1.0) + return probe_corr, polar_int, polar_int_corr, coefs_all -def cartesian_to_polar_transform_2Ddata( - im_cart, - xy_center, - num_theta_bins=180, - radius_max=None, +def aberrations_basis_function( + probe_size, + probe_sampling, + max_angular_order, + max_radial_order, + xp=np, ): - """ - Quick cartesian to polar conversion. - """ + """ """ + sx, sy = probe_size + dx, dy = probe_sampling + qx = xp.fft.fftfreq(sx, dx) + qy = xp.fft.fftfreq(sy, dy) - # coordinates - if radius_max is None: - radius_max = np.min(np.array(im_cart.shape) // 2) + qxa, qya = xp.meshgrid(qx, qy, indexing="ij") + q2 = qxa**2 + qya**2 + theta = xp.arctan2(qya, qxa) - r = np.arange(radius_max) - t = np.linspace( - 0, - 2.0 * np.pi, - num_theta_bins, - endpoint=False, - ) - ra, ta = np.meshgrid(r, t) + basis = [] + index = [] - # resampling coordinates - x = ra * np.cos(ta) + xy_center[0] - y = ra * np.sin(ta) + xy_center[1] + for n in range(max_angular_order + 1): + for m in range((max_radial_order - n) // 2 + 1): + basis.append((q2 ** (m + n / 2) * np.cos(n * theta))) + index.append((m, n, 0)) + if n > 0: + basis.append((q2 ** (m + n / 2) * np.sin(n * theta))) + index.append((m, n, 1)) - xf = np.floor(x).astype("int") - yf = np.floor(y).astype("int") - dx = x - xf - dy = y - yf + basis = xp.array(basis) - # resample image - im_polar = ( - im_cart.ravel()[ - np.ravel_multi_index( - (xf, yf), - im_cart.shape, - mode="wrap", - ) - ] - * (1 - dx) - * (1 - dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf + 1, yf), - im_cart.shape, - mode="wrap", - ) - ] - * (dx) - * (1 - dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf, yf + 1), - im_cart.shape, - mode="wrap", - ) - ] - * (1 - dx) - * (dy) - + im_cart.ravel()[ - np.ravel_multi_index( - (xf + 1, yf + 1), - im_cart.shape, - mode="wrap", - ) - ] - * (dx) - * (dy) - ) - - return im_polar + return basis, index -def polar_to_cartesian_transform_2Ddata( - im_polar, - xy_size, - xy_center, +def fit_aberration_surface( + complex_probe, + probe_sampling, + max_angular_order, + max_radial_order, + seed=1, + xp=np, ): - """ - Quick cartesian to polar conversion. - """ + """ """ + probe_amp = xp.abs(complex_probe) + probe_angle = xp.angle(complex_probe) - # coordinates - sx, sy = xy_size - cx, cy = xy_center + if xp is np: + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True, seed=seed) + else: + unwrapped_angle = xp.asarray( + unwrap_phase(xp.asnumpy(probe_angle), wrap_around=True, seed=seed) + ) - x = np.fft.fftfreq(sx, d=1 / sx) - y = np.fft.fftfreq(sy, d=1 / sy) - xa, ya = np.meshgrid(x, y, indexing="ij") - ra = np.hypot(xa - cx, ya - cy) - ta = np.arctan2(ya, xa) + basis, _ = aberrations_basis_function( + complex_probe.shape, + probe_sampling, + max_angular_order, + max_radial_order, + xp=xp, + ) - t = np.linspace(0, 2 * np.pi, im_polar.shape[0], endpoint=False) - t_step = t[1] - t[0] + raveled_basis = basis.reshape((basis.shape[0], -1)) + raveled_weights = probe_amp.ravel() - # resampling coordinates - t_ind = ta / t_step - r_ind = ra.copy() - tf = np.floor(t_ind).astype("int") - rf = np.floor(r_ind).astype("int") - dt = t_ind - tf - dr = r_ind - rf + Aw = raveled_basis.T * raveled_weights[:, None] + bw = unwrapped_angle.ravel() * raveled_weights + coeff = xp.linalg.lstsq(Aw, bw, rcond=None)[0] - # resample image - im_cart = im_polar.ravel()[ - np.ravel_multi_index( - (tf, rf), - im_polar.shape, - mode=("wrap", "clip"), - ) - ] + fitted_angle = xp.tensordot(coeff, basis, axes=1) - return im_cart + return fitted_angle From 70ed4660782a923b1388fa68fa4b40be2ef157c2 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 11 Jul 2023 09:51:28 -0700 Subject: [PATCH 268/362] a bit of gpu cleaning --- .../process/phase/iterative_base_class.py | 3 --- py4DSTEM/process/phase/iterative_dpc.py | 11 +++++++- .../iterative_mixedstate_ptychography.py | 10 +++++++ .../iterative_multislice_ptychography.py | 10 +++++++ .../iterative_overlap_magnetic_tomography.py | 10 +++++++ .../phase/iterative_overlap_tomography.py | 10 +++++++ py4DSTEM/process/phase/iterative_parallax.py | 27 ++++++++++++++++++- .../iterative_simultaneous_ptychography.py | 10 +++++++ .../iterative_singleslice_ptychography.py | 10 +++++++ 9 files changed, 96 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_base_class.py b/py4DSTEM/process/phase/iterative_base_class.py index 76583815e..ae4c92d4b 100644 --- a/py4DSTEM/process/phase/iterative_base_class.py +++ b/py4DSTEM/process/phase/iterative_base_class.py @@ -161,8 +161,6 @@ def _preprocess_datacube_and_vacuum_probe( "Datacube calibration can only handle uniform Q-sampling." ) - Q_pixel_size = datacube.calibration.get_Q_pixel_size() - if com_shifts is not None: com_shifts = ( com_shifts[0] * resampling_factor_x, @@ -280,7 +278,6 @@ def _extract_intensities_and_calibrations_from_datacube( """ # Copies intensities to device casting to float32 - xp = self._xp intensities = datacube.data self._grid_scan_shape = intensities.shape[:2] diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index 4e890db79..e364069e8 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -368,6 +368,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _forward( @@ -512,7 +517,6 @@ def _object_gaussian_constraint(self, current_object, gaussian_filter_sigma): constrained_object: np.ndarray Constrained object estimate """ - xp = self._xp gaussian_filter = self._gaussian_filter gaussian_filter_sigma /= self.sampling[0] @@ -815,6 +819,11 @@ def reconstruct( ] self.object_phase = asnumpy(self._object_phase) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration( diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index d4e2e5346..c80ec1062 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -574,6 +574,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -1727,6 +1732,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index d477da8ce..66c943ec6 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -673,6 +673,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -2149,6 +2154,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 939f42dec..75a8423a0 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -905,6 +905,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection( @@ -2540,6 +2545,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _crop_rotate_object_manually( diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 6b0a16e2e..c8f4487b5 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -817,6 +817,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -2261,6 +2266,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _crop_rotate_object_manually( diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index 576342631..d55d5c353 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -172,7 +172,6 @@ def preprocess( require_calibrations=True, ) self._intensities = xp.asarray(self._intensities, dtype=xp.float32) - # make sure mean diffraction pattern is shaped correctly if (self._dp_mean.shape[0] != self._intensities.shape[2]) or ( self._dp_mean.shape[1] != self._intensities.shape[3] @@ -377,6 +376,12 @@ def preprocess( ax.set_title("Average Bright Field Image") self._preprocessed = True + + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def tune_angle_and_defocus( @@ -827,6 +832,11 @@ def reconstruct( self.recon_BF = asnumpy(self._recon_BF) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def aberration_fit( @@ -876,6 +886,11 @@ def aberration_fit( ) / 2.0 # factor /2 for A1 astigmatism? /4? self.aberration_A1y = (m_aberration[1, 0] + m_aberration[0, 1]) / 2.0 + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + # Print results if self._verbose: print( @@ -1061,6 +1076,11 @@ def aberration_correct( self._recon_phase_corrected = xp.real(xp.fft.ifft2(im_fft_corr)) self.recon_phase_corrected = asnumpy(self._recon_phase_corrected) + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + # plotting if plot_corrected_phase: figsize = kwargs.pop("figsize", (6, 6)) @@ -1219,6 +1239,11 @@ def depth_section( ax.set_yticks([]) ax.set_title(f"Depth section: {dz}A") + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return stack_depth def _crop_padded_object( diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 545900634..8904012b2 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -814,6 +814,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _warmup_overlap_projection(self, current_object, current_probe): @@ -2926,6 +2931,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index bd7d57d68..86878e78e 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -542,6 +542,11 @@ def preprocess( self._preprocessed = True + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _overlap_projection(self, current_object, current_probe): @@ -1633,6 +1638,11 @@ def reconstruct( self.probe = self.probe_centered self.error = error.item() + if self._device == "gpu": + xp = self._xp + xp._default_memory_pool.free_all_blocks() + xp.clear_memo() + return self def _visualize_last_iteration_figax( From 689c5b125bca9cba91eee1e1ba6b0a73dbd9d34c Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 11:09:24 -0700 Subject: [PATCH 269/362] removing unnecessary self._xp --- py4DSTEM/process/phase/iterative_dpc.py | 2 -- py4DSTEM/process/phase/iterative_mixedstate_ptychography.py | 2 -- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 2 -- .../process/phase/iterative_overlap_magnetic_tomography.py | 2 -- py4DSTEM/process/phase/iterative_overlap_tomography.py | 2 -- py4DSTEM/process/phase/iterative_parallax.py | 4 ---- py4DSTEM/process/phase/iterative_simultaneous_ptychography.py | 2 -- py4DSTEM/process/phase/iterative_singleslice_ptychography.py | 2 -- 8 files changed, 18 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index e364069e8..b3d449fca 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -369,7 +369,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -820,7 +819,6 @@ def reconstruct( self.object_phase = asnumpy(self._object_phase) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index c80ec1062..69b2d8c45 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -575,7 +575,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1733,7 +1732,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 66c943ec6..4706decf9 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -674,7 +674,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2155,7 +2154,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 75a8423a0..4dd7c3dbb 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -906,7 +906,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2546,7 +2545,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index c8f4487b5..b5a3f71fa 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -818,7 +818,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2267,7 +2266,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_parallax.py b/py4DSTEM/process/phase/iterative_parallax.py index d55d5c353..80cdd8cd8 100644 --- a/py4DSTEM/process/phase/iterative_parallax.py +++ b/py4DSTEM/process/phase/iterative_parallax.py @@ -378,7 +378,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -833,7 +832,6 @@ def reconstruct( self.recon_BF = asnumpy(self._recon_BF) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -887,7 +885,6 @@ def aberration_fit( self.aberration_A1y = (m_aberration[1, 0] + m_aberration[0, 1]) / 2.0 if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1077,7 +1074,6 @@ def aberration_correct( self.recon_phase_corrected = asnumpy(self._recon_phase_corrected) if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index 8904012b2..cf243192e 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -815,7 +815,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -2932,7 +2931,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 86878e78e..5691828f2 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -543,7 +543,6 @@ def preprocess( self._preprocessed = True if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() @@ -1639,7 +1638,6 @@ def reconstruct( self.error = error.item() if self._device == "gpu": - xp = self._xp xp._default_memory_pool.free_all_blocks() xp.clear_memo() From 793f36a4a95bee1df24f29f24b839cda04f5e29f Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 15:55:20 -0700 Subject: [PATCH 270/362] bugfixes for probe constraints --- .../iterative_ptychographic_constraints.py | 3 +- py4DSTEM/process/phase/utils.py | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index d3c5b34a9..5fe1a1a35 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -412,6 +412,7 @@ def _probe_fourier_amplitude_constraint( updated_probe_fft, _, _, _ = regularize_probe_amplitude( asnumpy(current_probe_fft), width_max_pixels=width_max_pixels, + nearest_angular_neighbor_averaging=5, enforce_constant_intensity=enforce_constant_intensity, corner_centered=True, ) @@ -485,7 +486,7 @@ def _probe_aberration_fitting_constraint( fourier_probe_abs = xp.abs(fourier_probe) sampling = self.sampling - fitted_angle = fit_aberration_surface( + fitted_angle, _ = fit_aberration_surface( fourier_probe, sampling, max_angular_order, diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 7f5287b3b..2d36284ee 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -12,10 +12,11 @@ cp = None from scipy.fft import dstn, idstn + from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom from py4DSTEM.process.utils import get_CoM -from scipy.ndimage import gaussian_filter +from scipy.ndimage import gaussian_filter, uniform_filter1d from skimage.restoration import unwrap_phase # fmt: off @@ -1282,7 +1283,7 @@ def nesterov_gamma(zero_indexed_iter_num): def cartesian_to_polar_transform_2Ddata( im_cart, xy_center, - num_theta_bins=180, + num_theta_bins=90, radius_max=None, corner_centered=False, xp=np, @@ -1411,6 +1412,7 @@ def polar_to_cartesian_transform_2Ddata( def regularize_probe_amplitude( probe_init, width_max_pixels=2.0, + nearest_angular_neighbor_averaging=5, enforce_constant_intensity=True, corner_centered=False, ): @@ -1423,6 +1425,8 @@ def regularize_probe_amplitude( 2D complex image of the probe in Fourier space. width_max_pixels: float Maximum edge width of the probe in pixels. + nearest_angular_neighbor_averaging: int + Number of nearest angular neighbor pixels to average to make aperture less jagged. enforce_constant_intensity: bool Set to true to make intensity inside the aperture constant. corner_centered: bool @@ -1504,6 +1508,17 @@ def step_model(radius, sig_0, rad_0, width): xtol=1e-12, bounds=(lb, ub), )[0] + # polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) + + # make aperture less jagged, using moving mean + coefs_all = np.apply_along_axis( + uniform_filter1d, + 0, + coefs_all, + size=nearest_angular_neighbor_averaging, + mode="wrap", + ) + for a0 in range(polar_int.shape[0]): polar_int_corr[a0, :] = step_model(radius, *coefs_all[a0, :]) # Convert back to cartesian coordinates @@ -1564,7 +1579,6 @@ def fit_aberration_surface( probe_sampling, max_angular_order, max_radial_order, - seed=1, xp=np, ): """ """ @@ -1572,11 +1586,12 @@ def fit_aberration_surface( probe_angle = xp.angle(complex_probe) if xp is np: - unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True, seed=seed) + probe_angle = probe_angle.astype(np.float64) + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True).astype(xp.float32) else: - unwrapped_angle = xp.asarray( - unwrap_phase(xp.asnumpy(probe_angle), wrap_around=True, seed=seed) - ) + probe_angle = xp.asnumpy(probe_angle).astype(np.float64) + unwrapped_angle = unwrap_phase(probe_angle, wrap_around=True) + unwrapped_angle = xp.asarray(unwrapped_angle).astype(xp.float32) basis, _ = aberrations_basis_function( complex_probe.shape, @@ -1595,4 +1610,4 @@ def fit_aberration_surface( fitted_angle = xp.tensordot(coeff, basis, axes=1) - return fitted_angle + return fitted_angle, coeff From 2864b2457070b5c9f7764c9989b5e2a33a0c7fe1 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:27:57 -0700 Subject: [PATCH 271/362] probe constraints for mixed-state --- .../iterative_mixedstate_ptychography.py | 95 +++++++++---------- .../iterative_singleslice_ptychography.py | 12 +-- 2 files changed, 51 insertions(+), 56 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py index 69b2d8c45..56fec1004 100644 --- a/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py +++ b/py4DSTEM/process/phase/iterative_mixedstate_ptychography.py @@ -1106,15 +1106,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1145,14 +1145,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed - symmetrize_probe: bool - If True, the probe is radially-averaged + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1160,10 +1158,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray @@ -1232,16 +1231,14 @@ def _constraints( current_probe = self._probe_center_of_mass_constraint(current_probe) # These constraints don't _really_ make sense for mixed-state - if probe_gaussian_filter: - raise NotImplementedError() - if symmetrize_probe: - raise NotImplementedError() if fix_probe_aperture: raise NotImplementedError() - elif constrain_probe_amplitude: - raise NotImplementedError() elif constrain_probe_fourier_amplitude: raise NotImplementedError() + if fit_probe_aberrations: + raise NotImplementedError() + if constrain_probe_amplitude: + raise NotImplementedError() if orthogonalize_probe: current_probe = self._probe_orthogonalization_constraint(current_probe) @@ -1276,19 +1273,19 @@ def reconstruct( orthogonalize_probe: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1342,19 +1339,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate global_affine_transformation: bool, optional @@ -1363,12 +1359,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -1685,12 +1681,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -1698,7 +1688,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, diff --git a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py index 5691828f2..0480bae8a 100644 --- a/py4DSTEM/process/phase/iterative_singleslice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_singleslice_ptychography.py @@ -1270,12 +1270,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float From a1a1cca2c071e7b2894d0040ea1860b07da728ce Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:37:46 -0700 Subject: [PATCH 272/362] probe constraints for multislice --- .../iterative_multislice_ptychography.py | 117 +++++++++--------- 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 4706decf9..1e9bd2cbb 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -1455,15 +1455,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1498,14 +1498,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1513,10 +1511,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool If True, probe Fourier amplitude is replaced by initial_probe_aperture initial_probe_aperture: np.ndarray @@ -1612,31 +1611,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1668,20 +1665,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1740,19 +1737,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate global_affine_transformation: bool, optional @@ -1761,12 +1757,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2098,12 +2094,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2111,7 +2101,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, From 245957f8268550b620e488f68366b76d9a2aadb0 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:51:30 -0700 Subject: [PATCH 273/362] probe constraints for overlap tomography --- .../iterative_overlap_magnetic_tomography.py | 130 +++++++++--------- .../phase/iterative_overlap_tomography.py | 130 +++++++++--------- 2 files changed, 124 insertions(+), 136 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 4dd7c3dbb..875bce735 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -1685,15 +1685,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1725,14 +1725,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1740,10 +1738,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1836,31 +1835,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1892,21 +1889,21 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma_e: float = None, gaussian_filter_sigma_m: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass_e: float = None, q_lowpass_m: float = None, @@ -1960,19 +1957,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1986,12 +1982,12 @@ def reconstruct( Standard deviation of gaussian kernel for magnetic object in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2447,12 +2443,6 @@ def reconstruct( self._probe, self._positions_px_all[start_tilt:end_tilt], fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2460,7 +2450,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, @@ -2497,12 +2492,6 @@ def reconstruct( self._probe, None, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2510,7 +2499,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index b5a3f71fa..0293fd322 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -1533,15 +1533,15 @@ def _constraints( current_probe, current_positions, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -1569,14 +1569,12 @@ def _constraints( Current positions estimate fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - probe_gaussian_filter: bool - If True, applies reciprocal-space gaussian filtering on residual aberrations - probe_gaussian_filter_sigma: float - Standard deviation of gaussian kernel in A^-1 - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -1584,10 +1582,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -1649,31 +1648,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -1705,20 +1702,20 @@ def reconstruct( fix_com: bool = True, fix_probe_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass: float = None, q_highpass: float = None, @@ -1770,19 +1767,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float, optional @@ -1794,12 +1790,12 @@ def reconstruct( Standard deviation of gaussian kernel in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass: float @@ -2176,12 +2172,6 @@ def reconstruct( self._probe, self._positions_px_all[start_tilt:end_tilt], fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2189,7 +2179,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, @@ -2221,12 +2216,6 @@ def reconstruct( self._probe, None, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2234,7 +2223,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=True, From 8aa3b60d58fbf44ed813189509bf443ec5161611 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 16:56:03 -0700 Subject: [PATCH 274/362] probe constraints for simultaneous --- .../iterative_simultaneous_ptychography.py | 111 +++++++++--------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py index cf243192e..8881d021c 100644 --- a/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py +++ b/py4DSTEM/process/phase/iterative_simultaneous_ptychography.py @@ -2210,15 +2210,15 @@ def _constraints( current_positions, pure_phase_object, fix_com, - symmetrize_probe, - probe_gaussian_filter, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, + fit_probe_aberrations, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, constrain_probe_amplitude, constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, constrain_probe_fourier_amplitude, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, fix_probe_aperture, initial_probe_aperture, fix_positions, @@ -2252,8 +2252,12 @@ def _constraints( If True, object amplitude is set to unity fix_com: bool If True, probe CoM is fixed to the center - symmetrize_probe: bool - If True, the probe is radially-averaged + fit_probe_aberrations: bool + If True, fits the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions constrain_probe_amplitude: bool If True, probe amplitude is constrained by top hat function constrain_probe_amplitude_relative_radius: float @@ -2261,10 +2265,11 @@ def _constraints( constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + If True, probe aperture is constrained by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_probe_aperture: bool, If True, probe Fourier amplitude is replaced by initial probe aperture. initial_probe_aperture: np.ndarray, @@ -2364,31 +2369,29 @@ def _constraints( if fix_com: current_probe = self._probe_center_of_mass_constraint(current_probe) - if probe_gaussian_filter: - current_probe = self._probe_residual_aberration_filtering_constraint( - current_probe, - probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude, - ) - - if symmetrize_probe: - current_probe = self._probe_radial_symmetrization_constraint(current_probe) - if fix_probe_aperture: current_probe = self._probe_aperture_constraint( current_probe, initial_probe_aperture, ) - elif constrain_probe_amplitude: - current_probe = self._probe_amplitude_constraint( - current_probe, - constrain_probe_amplitude_relative_radius, - constrain_probe_amplitude_relative_width, - ) elif constrain_probe_fourier_amplitude: current_probe = self._probe_fourier_amplitude_constraint( current_probe, - constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity, + ) + + if fit_probe_aberrations: + current_probe = self._probe_aberration_fitting_constraint( + current_probe, + fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order, + ) + + if constrain_probe_amplitude: + current_probe = self._probe_amplitude_constraint( + current_probe, + constrain_probe_amplitude_relative_radius, constrain_probe_amplitude_relative_width, ) @@ -2422,21 +2425,21 @@ def reconstruct( fix_probe_iter: int = 0, warmup_iter: int = 0, fix_probe_aperture_iter: int = 0, - symmetrize_probe_iter: int = 0, constrain_probe_amplitude_iter: int = 0, constrain_probe_amplitude_relative_radius: float = 0.5, constrain_probe_amplitude_relative_width: float = 0.05, constrain_probe_fourier_amplitude_iter: int = 0, - constrain_probe_fourier_amplitude_threshold: float = 0.9, + constrain_probe_fourier_amplitude_max_width_pixels: float = 3.0, + constrain_probe_fourier_amplitude_constant_intensity: bool = False, fix_positions_iter: int = np.inf, constrain_position_distance: float = None, global_affine_transformation: bool = True, gaussian_filter_sigma_e: float = None, gaussian_filter_sigma_m: float = None, gaussian_filter_iter: int = np.inf, - probe_gaussian_filter_sigma: float = None, - probe_gaussian_filter_residual_aberrations_iter: int = np.inf, - probe_gaussian_filter_fix_amplitude: bool = True, + fit_probe_aberrations_iter: int = 0, + fit_probe_aberrations_max_angular_order: int = 4, + fit_probe_aberrations_max_radial_order: int = 4, butterworth_filter_iter: int = np.inf, q_lowpass_e: float = None, q_lowpass_m: float = None, @@ -2492,19 +2495,18 @@ def reconstruct( Number of iterations to run with a fixed probe before updating probe estimate fix_probe_aperture_iter: int, optional Number of iterations to run with a fixed probe Fourier amplitude before updating probe estimate - symmetrize_probe_iter: int, optional - Number of iterations to run before radially-averaging the probe - constrain_probe_amplitude: bool - If True, probe amplitude is constrained by top hat function + constrain_probe_amplitude_iter: int, optional + Number of iterations to run while constraining the real-space probe with a top-hat support. constrain_probe_amplitude_relative_radius: float Relative location of top-hat inflection point, between 0 and 0.5 constrain_probe_amplitude_relative_width: float Relative width of top-hat sigmoid, between 0 and 0.5 - constrain_probe_fourier_amplitude: bool - If True, probe fourier amplitude is constrained by top hat function - constrain_probe_fourier_amplitude_threshold: float - Threshold value for current probe fourier mask. Value should - be between 0 and 1, where higher values provide the most masking. + constrain_probe_fourier_amplitude_iter: int, optional + Number of iterations to run while constraining the Fourier-space probe by fitting a sigmoid for each angular frequency. + constrain_probe_fourier_amplitude_max_width_pixels: float + Maximum pixel width of fitted sigmoid functions. + constrain_probe_fourier_amplitude_constant_intensity: bool + If True, the probe aperture is additionally constrained to a constant intensity. fix_positions_iter: int, optional Number of iterations to run with fixed positions before updating positions estimate constrain_position_distance: float @@ -2518,12 +2520,12 @@ def reconstruct( Standard deviation of gaussian kernel for magnetic object in A gaussian_filter_iter: int, optional Number of iterations to run using object smoothness constraint - probe_gaussian_filter_sigma: float, optional - Standard deviation of probe gaussian kernel in A^-1 - probe_gaussian_filter_residual_aberrations_iter: int, optional - Number of iterations to run using probe smoothing of residual aberrations - probe_gaussian_filter_fix_amplitude: bool - If True, only the probe phase is smoothed + fit_probe_aberrations_iter: int, optional + Number of iterations to run while fitting the probe aberrations to a low-order expansion + fit_probe_aberrations_max_angular_order: bool + Max angular order of probe aberrations basis functions + fit_probe_aberrations_max_radial_order: bool + Max radial order of probe aberrations basis functions butterworth_filter_iter: int, optional Number of iterations to run using high-pass butteworth filter q_lowpass_e: float @@ -2868,12 +2870,6 @@ def reconstruct( self._probe, self._positions_px, fix_com=fix_com and a0 >= fix_probe_iter, - symmetrize_probe=a0 < symmetrize_probe_iter, - probe_gaussian_filter=a0 - < probe_gaussian_filter_residual_aberrations_iter - and probe_gaussian_filter_sigma is not None, - probe_gaussian_filter_sigma=probe_gaussian_filter_sigma, - probe_gaussian_filter_fix_amplitude=probe_gaussian_filter_fix_amplitude, constrain_probe_amplitude=a0 < constrain_probe_amplitude_iter and a0 >= fix_probe_iter, constrain_probe_amplitude_relative_radius=constrain_probe_amplitude_relative_radius, @@ -2881,7 +2877,12 @@ def reconstruct( constrain_probe_fourier_amplitude=a0 < constrain_probe_fourier_amplitude_iter and a0 >= fix_probe_iter, - constrain_probe_fourier_amplitude_threshold=constrain_probe_fourier_amplitude_threshold, + constrain_probe_fourier_amplitude_max_width_pixels=constrain_probe_fourier_amplitude_max_width_pixels, + constrain_probe_fourier_amplitude_constant_intensity=constrain_probe_fourier_amplitude_constant_intensity, + fit_probe_aberrations=a0 < fit_probe_aberrations_iter + and a0 >= fix_probe_iter, + fit_probe_aberrations_max_angular_order=fit_probe_aberrations_max_angular_order, + fit_probe_aberrations_max_radial_order=fit_probe_aberrations_max_radial_order, fix_probe_aperture=a0 < fix_probe_aperture_iter, initial_probe_aperture=self._probe_initial_aperture, fix_positions=a0 < fix_positions_iter, From f6ed1080fe6d3658ce222d8b27721a139d126ed9 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Tue, 11 Jul 2023 17:04:43 -0700 Subject: [PATCH 275/362] imports, formatting, linting --- py4DSTEM/process/phase/.gitignore | 1 + py4DSTEM/process/phase/__init__.py | 29 ++++++++++++++----- py4DSTEM/process/phase/iterative_dpc.py | 2 +- .../iterative_overlap_magnetic_tomography.py | 6 +++- .../phase/iterative_overlap_tomography.py | 6 +++- .../iterative_ptychographic_constraints.py | 2 +- py4DSTEM/process/phase/utils.py | 5 ++-- 7 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 py4DSTEM/process/phase/.gitignore diff --git a/py4DSTEM/process/phase/.gitignore b/py4DSTEM/process/phase/.gitignore new file mode 100644 index 000000000..c97f963b3 --- /dev/null +++ b/py4DSTEM/process/phase/.gitignore @@ -0,0 +1 @@ +*.sh diff --git a/py4DSTEM/process/phase/__init__.py b/py4DSTEM/process/phase/__init__.py index cb9176375..178079349 100644 --- a/py4DSTEM/process/phase/__init__.py +++ b/py4DSTEM/process/phase/__init__.py @@ -3,13 +3,28 @@ _emd_hook = True from py4DSTEM.process.phase.iterative_dpc import DPCReconstruction -from py4DSTEM.process.phase.iterative_mixedstate_ptychography import MixedstatePtychographicReconstruction -from py4DSTEM.process.phase.iterative_multislice_ptychography import MultislicePtychographicReconstruction -from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import OverlapMagneticTomographicReconstruction -from py4DSTEM.process.phase.iterative_overlap_tomography import OverlapTomographicReconstruction +from py4DSTEM.process.phase.iterative_mixedstate_ptychography import ( + MixedstatePtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_multislice_ptychography import ( + MultislicePtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_overlap_magnetic_tomography import ( + OverlapMagneticTomographicReconstruction, +) +from py4DSTEM.process.phase.iterative_overlap_tomography import ( + OverlapTomographicReconstruction, +) from py4DSTEM.process.phase.iterative_parallax import ParallaxReconstruction -from py4DSTEM.process.phase.iterative_simultaneous_ptychography import SimultaneousPtychographicReconstruction -from py4DSTEM.process.phase.iterative_singleslice_ptychography import SingleslicePtychographicReconstruction -from py4DSTEM.process.phase.parameter_optimize import OptimizationParameter, PtychographyOptimizer +from py4DSTEM.process.phase.iterative_simultaneous_ptychography import ( + SimultaneousPtychographicReconstruction, +) +from py4DSTEM.process.phase.iterative_singleslice_ptychography import ( + SingleslicePtychographicReconstruction, +) +from py4DSTEM.process.phase.parameter_optimize import ( + OptimizationParameter, + PtychographyOptimizer, +) # fmt: on diff --git a/py4DSTEM/process/phase/iterative_dpc.py b/py4DSTEM/process/phase/iterative_dpc.py index b3d449fca..4c80ed177 100644 --- a/py4DSTEM/process/phase/iterative_dpc.py +++ b/py4DSTEM/process/phase/iterative_dpc.py @@ -4,7 +4,7 @@ """ import warnings -from typing import Tuple, Union, Sequence +from typing import Sequence, Tuple, Union import matplotlib.pyplot as plt import numpy as np diff --git a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py index 875bce735..6ca51f87b 100644 --- a/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_magnetic_tomography.py @@ -2487,7 +2487,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_overlap_tomography.py b/py4DSTEM/process/phase/iterative_overlap_tomography.py index 0293fd322..d6bee12fd 100644 --- a/py4DSTEM/process/phase/iterative_overlap_tomography.py +++ b/py4DSTEM/process/phase/iterative_overlap_tomography.py @@ -2211,7 +2211,11 @@ def reconstruct( if collective_tilt_updates: self._object += collective_object / self._num_tilts - (self._object, self._probe, _,) = self._constraints( + ( + self._object, + self._probe, + _, + ) = self._constraints( self._object, self._probe, None, diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index 5fe1a1a35..c5aef16c6 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -3,8 +3,8 @@ array_slice, estimate_global_transformation_ransac, fft_shift, - regularize_probe_amplitude, fit_aberration_surface, + regularize_probe_amplitude, ) from py4DSTEM.process.utils import get_CoM diff --git a/py4DSTEM/process/phase/utils.py b/py4DSTEM/process/phase/utils.py index 2d36284ee..c2e1d3b77 100644 --- a/py4DSTEM/process/phase/utils.py +++ b/py4DSTEM/process/phase/utils.py @@ -1,8 +1,8 @@ +import functools from typing import Mapping, Tuple, Union import matplotlib.pyplot as plt import numpy as np -import functools from scipy.optimize import curve_fit try: @@ -12,10 +12,9 @@ cp = None from scipy.fft import dstn, idstn - +from py4DSTEM.process.utils import get_CoM from py4DSTEM.process.utils.cross_correlate import align_and_shift_images from py4DSTEM.process.utils.utils import electron_wavelength_angstrom -from py4DSTEM.process.utils import get_CoM from scipy.ndimage import gaussian_filter, uniform_filter1d from skimage.restoration import unwrap_phase From 67dc9dc4c44a28281eb4a33aad39bc68ab70e7e1 Mon Sep 17 00:00:00 2001 From: Georgios Varnavides Date: Wed, 12 Jul 2023 11:34:13 -0700 Subject: [PATCH 276/362] commenting out probe renormalizations post-constraints --- .../iterative_ptychographic_constraints.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py index c5aef16c6..9af22ba92 100644 --- a/py4DSTEM/process/phase/iterative_ptychographic_constraints.py +++ b/py4DSTEM/process/phase/iterative_ptychographic_constraints.py @@ -364,7 +364,7 @@ def _probe_amplitude_constraint( erf = self._erf probe_intensity = xp.abs(current_probe) ** 2 - current_probe_sum = xp.sum(probe_intensity) + #current_probe_sum = xp.sum(probe_intensity) X = xp.fft.fftfreq(current_probe.shape[0])[:, None] Y = xp.fft.fftfreq(current_probe.shape[1])[None] @@ -374,10 +374,10 @@ def _probe_amplitude_constraint( tophat_mask = 0.5 * (1 - erf(sigma * r / (1 - r**2))) updated_probe = current_probe * tophat_mask - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_fourier_amplitude_constraint( self, @@ -406,7 +406,7 @@ def _probe_fourier_amplitude_constraint( xp = self._xp asnumpy = self._asnumpy - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + #current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft = xp.fft.fft2(current_probe) updated_probe_fft, _, _, _ = regularize_probe_amplitude( @@ -419,10 +419,10 @@ def _probe_fourier_amplitude_constraint( updated_probe_fft = xp.asarray(updated_probe_fft) updated_probe = xp.fft.ifft2(updated_probe_fft) - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_aperture_constraint( self, @@ -444,16 +444,16 @@ def _probe_aperture_constraint( """ xp = self._xp - current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) + #current_probe_sum = xp.sum(xp.abs(current_probe) ** 2) current_probe_fft_phase = xp.angle(xp.fft.fft2(current_probe)) updated_probe = xp.fft.ifft2( xp.exp(1j * current_probe_fft_phase) * initial_probe_aperture ) - updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) - normalization = xp.sqrt(current_probe_sum / updated_probe_sum) + #updated_probe_sum = xp.sum(xp.abs(updated_probe) ** 2) + #normalization = xp.sqrt(current_probe_sum / updated_probe_sum) - return updated_probe * normalization + return updated_probe #* normalization def _probe_aberration_fitting_constraint( self, From 2ebfb32509f01c12fbaf0421fadb6186360cd56a Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 13 Jul 2023 14:03:54 -0700 Subject: [PATCH 277/362] bragg vectors copy --- py4DSTEM/braggvectors/braggvectors.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index da8ffd3b2..366dbe9f8 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -285,7 +285,13 @@ def get_vectors( def copy(self, name=None): name = name if name is not None else self.name+"_copy" - braggvector_copy = BraggVectors(self.Rshape, self.Qshape, name=name) + braggvector_copy = BraggVectors( + self.Rshape, + self.Qshape, + name=name, + calibration = self.calibration.copy() + ) + braggvector_copy._v_uncal = self._v_uncal.copy() for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() From d693ed9ad35c66859dd963a7915c0658bf7b24bc Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 13 Jul 2023 14:12:35 -0700 Subject: [PATCH 278/362] bug fix --- py4DSTEM/braggvectors/braggvectors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 366dbe9f8..14b89fd98 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -226,7 +226,7 @@ def setcal( if pixel: assert(c.get_Q_pixel_size() is not None), "Requested calibration not found" if rotate: - assert(c.get_RQ_rotflip() is not None), "Requested calibration not found" + assert(c.get_QR_rotflip() is not None), "Requested calibration not found" # set the calibrations self._calstate = { From ab295ac1fa8ef1639271bd01233aa7657f4301ff Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 13 Jul 2023 15:21:52 -0700 Subject: [PATCH 279/362] bin and pad fixes --- py4DSTEM/preprocess/preprocess.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 6342a60ae..87cb689c5 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -262,10 +262,13 @@ def bin_data_diffraction( bin_factor, ).sum(axis=(3, 5)).astype(dtype) - # set dim vectors Qpixsize = datacube.calibration.get_Q_pixel_size() * bin_factor Qpixunits = datacube.calibration.get_Q_pixel_units() + + # set calibration pixel size + datacube.calibration.set_Q_pixel_size(Qpixsize) + datacube.set_dim( 2, [0,Qpixsize], @@ -278,8 +281,6 @@ def bin_data_diffraction( units = Qpixunits, name = 'Qy' ) - # set calibration pixel size - datacube.calibration.set_Q_pixel_size(Qpixsize) # return return datacube @@ -753,6 +754,22 @@ def pad_data_diffraction(datacube, pad_factor=None, output_size=None): datacube.data = np.pad(datacube.data, pad_width=pad_width, mode="constant") + Qpixsize = datacube.calibration.get_Q_pixel_size() + Qpixunits = datacube.calibration.get_Q_pixel_units() + + datacube.set_dim( + 2, + [0,Qpixsize], + units = Qpixunits, + name = 'Qx' + ) + datacube.set_dim( + 3, + [0,Qpixsize], + units = Qpixunits, + name = 'Qy' + ) + return datacube From 7e266f2774c6123556570c060ebb5fefad979394 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 13 Jul 2023 18:00:38 -0700 Subject: [PATCH 280/362] another bin and pad fix --- py4DSTEM/preprocess/preprocess.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 87cb689c5..c156c228e 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -266,9 +266,7 @@ def bin_data_diffraction( Qpixsize = datacube.calibration.get_Q_pixel_size() * bin_factor Qpixunits = datacube.calibration.get_Q_pixel_units() - # set calibration pixel size - datacube.calibration.set_Q_pixel_size(Qpixsize) - + datacube.set_dim( 2, [0,Qpixsize], @@ -282,6 +280,10 @@ def bin_data_diffraction( name = 'Qy' ) + # set calibration pixel size + datacube.calibration.set_Q_pixel_size(Qpixsize) + + # return return datacube @@ -770,6 +772,8 @@ def pad_data_diffraction(datacube, pad_factor=None, output_size=None): name = 'Qy' ) + datacube.calibrate() + return datacube From bde93c5c8c6fe71729d630f088cb8ba2bf837d87 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 21:48:25 -0400 Subject: [PATCH 281/362] updates --- py4DSTEM/process/strain.py | 402 ++++++++++++++++++++++++++---- py4DSTEM/visualize/vis_special.py | 96 ------- test/test_strain.py | 2 + 3 files changed, 351 insertions(+), 149 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index e999c02d1..3088afa51 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -1,10 +1,12 @@ # Defines the Strain class import numpy as np +import matplotlib.pyplot as plt from typing import Optional from py4DSTEM.data import RealSlice, Data from py4DSTEM.braggvectors import BraggVectors - +from py4DSTEM.preprocess.utils import get_maxima_2D +from py4DSTEM.visualize import show,add_pointlabels,add_vector class StrainMap(RealSlice,Data): @@ -45,19 +47,26 @@ def __init__( ) # set up braggvectors + # this assigns the bvs, ensures the origin is calibrated, + # and adds the strainmap to the bvs' tree self.braggvectors = braggvectors - # TODO - how to handle changes to braggvectors - # option: register with calibrations and add a .calibrate method - # which {{does something}} when origin changes - # TODO - include ellipse cal or no? - - assert(self.root is not None) # initialize as Data - Data.__init__( - self, - calibration = self.braggvectors.calibration - ) + Data.__init__(self) + + # set calstate + # this property is used only to check to make sure that + # the braggvectors being used throughout a workflow are + # the same. The state of calibration of the vectors is noted + # here, and then checked each time the vectors are used - + # if they differ, an error message and instructions for + # re-calibration are issued + self.calstate = self.braggvectors.calstate + + # get the BVM + # a new BVM using the current calstate is computed + self.bvm = self.braggvectors.histogram() + # braggvector properties @@ -73,6 +82,20 @@ def braggvectors(self,x): self._braggvectors.tree(self,force=True) + def reset_calstate(self): + """ + Resets the calibration state. This recomputes the BVM, and removes any computations + this StrainMap instance has stored, which will need to be recomputed. + """ + del( + self.g0, + self.g1, + self.g2, + ) + self.calstate = self.braggvectors.calstate + pass + + # Class methods @@ -81,8 +104,6 @@ def choose_lattice_vectors( index_g0, index_g1, index_g2, - mode = 'centered', - plot = True, subpixel = 'multicorr', upsample_factor = 16, sigma=0, @@ -92,39 +113,94 @@ def choose_lattice_vectors( minSpacing=0, edgeBoundary=1, maxNumPeaks=10, - bvm_vis_params = {}, + figsize=(12,6), + c_indices='lightblue', + c0='g', + c1='r', + c2='r', + c_vectors='r', + c_vectorlabels='w', + size_indices=20, + width_vectors=1, + size_vectorlabels=20, + vis_params = {}, returncalc = False, + returnfig=False, ): """ Choose which lattice vectors to use for strain mapping. - Args: - index_g0 (int): origin - index_g1 (int): second point of vector 1 - index_g2 (int): second point of vector 2 - mode (str): centered or raw bragg map - plot (bool): plot bragg vector maps and vectors - subpixel (str): specifies the subpixel resolution algorithm to use. - must be in ('pixel','poly','multicorr'), which correspond - to pixel resolution, subpixel resolution by fitting a - parabola, and subpixel resultion by Fourier upsampling. - upsample_factor: the upsampling factor for the 'multicorr' - algorithm - sigma: if >0, applies a gaussian filter - maxNumPeaks: the maximum number of maxima to return - minAbsoluteIntensity, minRelativeIntensity, relativeToPeak, - minSpacing, edgeBoundary, maxNumPeaks: filtering applied - after maximum detection and before subpixel refinement + Overlays the bvm with the points detected via local 2D + maxima detection, plus an index for each point. User selects + 3 points using the overlaid indices, which are identified as + the origin and the termini of the lattice vectors g1 and g2. + + Parameters + ---------- + index_g0 : int + selected index for the origin + index_g1 : int + selected index for g1 + index_g2 :int + selected index for g2 + subpixel : str in ('pixel','poly','multicorr') + See the docstring for py4DSTEM.preprocess.get_maxima_2D + upsample_factor : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + sigma : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + minAbsoluteIntensity : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + minRelativeIntensity : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + relativeToPeak : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + minSpacing : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + edgeBoundary : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + maxNumPeaks : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + figsize : 2-tuple + the size of the figure + c_indices : color + color of the maxima + c0 : color + color of the origin + c1 : color + color of g1 point + c2 : color + color of g2 point + c_vectors : color + color of the g1/g2 vectors + c_vectorlabels : color + color of the vector labels + size_indices : number + size of the indices + width_vectors : number + width of the vectors + size_vectorlabels : number + size of the vector labels + vis_params : dict + additional visualization parameters passed to `show` + returncalc : bool + toggles returning the answer + returnfig : bool + toggles returning the figure + + Returns + ------- + (optional) : None or (g0,g1,g2) or (fig,(ax1,ax2)) or both of the latter """ - from py4DSTEM.process.utils import get_maxima_2D - - if mode == "centered": - bvm = self.bvm_centered - else: - bvm = self.bvm_raw + # validate inputs + for i in (index_g0,index_g1,index_g2): + assert isinstance(i,(int,np.integer)), "indices must be integers!" + # check the calstate + assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + # find the maxima g = get_maxima_2D( - bvm, + self.bvm.data, subpixel = subpixel, upsample_factor = upsample_factor, sigma = sigma, @@ -136,26 +212,246 @@ def choose_lattice_vectors( maxNumPeaks = maxNumPeaks, ) - self.g = g - - from py4DSTEM.visualize import select_lattice_vectors - g1,g2 = select_lattice_vectors( - bvm, - gx = g['x'], - gy = g['y'], - i0 = index_g0, - i1 = index_g1, - i2 = index_g2, - **bvm_vis_params, - ) - + # get the lattice vectors + gx,gy = g['x'],g['y'] + g0 = gx[index_g0],gy[index_g0] + g1x = gx[index_g1] - g0[0] + g1y = gy[index_g1] - g0[1] + g2x = gx[index_g2] - g0[0] + g2y = gy[index_g2] - g0[1] + g1,g2 = (g1x,g1y),(g2x,g2y) + + # make the figure + fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) + show(self.bvm.data,figax=(fig,ax1),**vis_params) + show(self.bvm.data,figax=(fig,ax2),**vis_params) + + # Add indices to left panel + d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} + d0 = {'x':gx[index_g0],'y':gy[index_g0],'size':size_indices, + 'color':c0,'fontweight':'bold','labels':[str(index_g0)]} + d1 = {'x':gx[index_g1],'y':gy[index_g1],'size':size_indices, + 'color':c1,'fontweight':'bold','labels':[str(index_g1)]} + d2 = {'x':gx[index_g2],'y':gy[index_g2],'size':size_indices, + 'color':c2,'fontweight':'bold','labels':[str(index_g2)]} + add_pointlabels(ax1,d) + add_pointlabels(ax1,d0) + add_pointlabels(ax1,d1) + add_pointlabels(ax1,d2) + + # Add vectors to right panel + dg1 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g1[0],'vy':g1[1],'width':width_vectors, + 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} + dg2 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g2[0],'vy':g2[1],'width':width_vectors, + 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} + add_vector(ax2,dg1) + add_vector(ax2,dg2) + + # store vectors + self.g0 = g0 self.g1 = g1 self.g2 = g2 - if returncalc: - return g1, g2 + # return + if returncalc and returnfig: + return (g0,g1,g2),(fig,(ax1,ax2)) + elif returncalc: + return (g0,g1,g2) + elif returnfig: + return (fig,(ax1,ax2)) + else: + return + + + + + + + + + + + + + + + +def index_bragg_directions(x0, y0, gx, gy, g1, g2): + """ + From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + reciprocal lattice directions. + + The approach is to solve the matrix equation + ``alpha = beta * M`` + where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, + beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the + h,k indices. + + Args: + x0 (float): x-coord of origin + y0 (float): y-coord of origin + gx (1d array): x-coord of the reciprocal lattice vectors + gy (1d array): y-coord of the reciprocal lattice vectors + g1 (2-tuple of floats): g1x,g1y + g2 (2-tuple of floats): g2x,g2y + + Returns: + (3-tuple) A 3-tuple containing: + + * **h**: *(ndarray of ints)* first index of the bragg directions + * **k**: *(ndarray of ints)* second index of the bragg directions + * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the + indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y + coords 'h' and 'k' contain h and k. + """ + # Get beta, the matrix of lattice vectors + beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + + # Get alpha, the matrix of measured bragg angles + alpha = np.vstack([gx-x0,gy-y0]) + + # Calculate M, the matrix of peak positions + M = lstsq(beta, alpha, rcond=None)[0].T + M = np.round(M).astype(int) + # Get h,k + h = M[:,0] + k = M[:,1] + # Store in a PointList + coords = [('qx',float),('qy',float),('h',int),('k',int)] + temp_array = np.zeros([], dtype = coords) + bragg_directions = PointList(data = temp_array) + bragg_directions.add_data_by_field((gx,gy,h,k)) + + return h,k, bragg_directions + + + +def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, + qy_shift=0, mask=None): + """ + Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + identify the indices for each peak in the PointListArray braggpeaks. + Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + indices with the ints (h,k) and indicating whether the peak was successfully indexed + or not with the bool index_mask. If `mask` is specified, only the locations where + mask is True are indexed. + + Args: + braggpeaks (PointListArray): the braggpeaks to index. Must contain + the coordinates 'qx', 'qy', and 'intensity' + lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. + Must contain the coordinates 'qx', 'qy', 'h', and 'k' + maxPeakSpacing (float): Maximum distance from the ideal lattice points + to include a peak for indexing + qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + relative to the `braggpeaks` PointListArray + mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + locations should be indexed. This can be used to index different regions of + the scan with different lattices + + Returns: + (PointListArray): The original braggpeaks pointlistarray, with new coordinates + 'h', 'k', containing the indices of each indexable peak. + """ + + assert isinstance(braggpeaks,PointListArray) + assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) + assert isinstance(lattice, PointList) + assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + + if mask is None: + mask = np.ones(braggpeaks.shape,dtype=bool) + + assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' + assert mask.dtype == bool, 'mask must be boolean' + + indexed_braggpeaks = braggpeaks.copy() + + # add the coordinates if they don't exist + if not ('h' in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) + if not ('k' in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + + # loop over all the scan positions + for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): + if mask[Rx,Ry]: + pl = indexed_braggpeaks.get_pointlist(Rx,Ry) + rm_peak_mask = np.zeros(pl.length,dtype=bool) + + for i in range(pl.length): + r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ + (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 + ind = np.argmin(r2) + if r2[ind] <= maxPeakSpacing**2: + pl.data['h'][i] = lattice.data['h'][ind] + pl.data['k'][i] = lattice.data['k'][ind] + else: + rm_peak_mask[i] = True + pl.remove(rm_peak_mask) + + indexed_braggpeaks.name = braggpeaks.name + "_indexed" + return indexed_braggpeaks + + + + + + + + + + + + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): + """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). + """ + fig,ax = show(ar,returnfig=True,**kwargs) + + # Add vectors + dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, + 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} + dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, + 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} + add_vector(ax,dg1) + add_vector(ax,dg2) + + if returnfig: + return fig,ax + else: + plt.show() + return + + + def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, + points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): + """ + Shows an array with an overlay describing the Bragg directions + + Accepts: + ar (arrray) the image + bragg_directions (PointList) the bragg scattering directions; must have coordinates + 'qx','qy','h', and 'k'. Optionally may also have 'l'. + """ + assert isinstance(braggdirections,PointList) + for k in ('qx','qy','h','k'): + assert k in braggdirections.data.dtype.fields + + fig,ax = show(ar,returnfig=True,**kwargs) + d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, + 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} + add_bragg_index_labels(ax,d) + + if returnfig: + return fig,ax + else: + plt.show() + return diff --git a/py4DSTEM/visualize/vis_special.py b/py4DSTEM/visualize/vis_special.py index b487048e2..43cf7fff8 100644 --- a/py4DSTEM/visualize/vis_special.py +++ b/py4DSTEM/visualize/vis_special.py @@ -590,102 +590,6 @@ def select_point(ar,x,y,i,color='lightblue',color_selected='r',size=20,returnfig return -def select_lattice_vectors(ar,gx,gy,i0,i1,i2, - c_indices='lightblue',c0='g',c1='r',c2='r',c_vectors='r',c_vectorlabels='w', - size_indices=20,width_vectors=1,size_vectorlabels=20, - figsize=(12,6),returnfig=False,**kwargs): - """ - This function accepts a set of reciprocal lattice points (gx,gy) and three indices - (i0,i1,i2). Using those indices as, respectively, the origin, the endpoint of g1, and - the endpoint of g2, this function computes the basis lattice vectors g1,g2, visualizes - them, and returns them. To compute these vectors without visualizing, use - latticevectors.get_selected_lattice_vectors(). - - Returns: - if returnfig==False: g1,g2 - if returnfig==True g1,g2,fig,ax - """ - from py4DSTEM.process.latticevectors import get_selected_lattice_vectors - - # Make the figure - fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) - show(ar,figax=(fig,ax1),**kwargs) - show(ar,figax=(fig,ax2),**kwargs) - - # Add indices to left panel - d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} - d0 = {'x':gx[i0],'y':gy[i0],'size':size_indices,'color':c0,'fontweight':'bold','labels':[str(i0)]} - d1 = {'x':gx[i1],'y':gy[i1],'size':size_indices,'color':c1,'fontweight':'bold','labels':[str(i1)]} - d2 = {'x':gx[i2],'y':gy[i2],'size':size_indices,'color':c2,'fontweight':'bold','labels':[str(i2)]} - add_pointlabels(ax1,d) - add_pointlabels(ax1,d0) - add_pointlabels(ax1,d1) - add_pointlabels(ax1,d2) - - # Compute vectors - g1,g2 = get_selected_lattice_vectors(gx,gy,i0,i1,i2) - - # Add vectors to right panel - dg1 = {'x0':gx[i0],'y0':gy[i0],'vx':g1[0],'vy':g1[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - dg2 = {'x0':gx[i0],'y0':gy[i0],'vx':g2[0],'vy':g2[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - add_vector(ax2,dg1) - add_vector(ax2,dg2) - - if returnfig: - return g1,g2,fig,(ax1,ax2) - else: - plt.show() - return g1,g2 - - -def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) - - # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) - - if returnfig: - return fig,ax - else: - plt.show() - return - - -def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, - points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): - """ - Shows an array with an overlay describing the Bragg directions - - Accepts: - ar (arrray) the image - bragg_directions (PointList) the bragg scattering directions; must have coordinates - 'qx','qy','h', and 'k'. Optionally may also have 'l'. - """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) - - if returnfig: - return fig,ax - else: - plt.show() - return - - def show_max_peak_spacing(ar,spacing,braggdirections,color='g',lw=2,returnfig=False,**kwargs): """ Show a circle of radius `spacing` about each Bragg direction """ diff --git a/test/test_strain.py b/test/test_strain.py index 5bfa0efd3..bc9b8b58c 100644 --- a/test/test_strain.py +++ b/test/test_strain.py @@ -27,5 +27,7 @@ def test_strainmap_instantiation(self): ) assert(isinstance(strainmap, StrainMap)) + assert(strainmap.calibration is not None) + assert(strainmap.calibration is strainmap.braggvectors.calibration) From 884450d286d3b676122bd8c964193a3a9309e71e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 22:49:42 -0400 Subject: [PATCH 282/362] fix --- py4DSTEM/process/strain.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 3088afa51..07dcb91bd 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -87,11 +87,13 @@ def reset_calstate(self): Resets the calibration state. This recomputes the BVM, and removes any computations this StrainMap instance has stored, which will need to be recomputed. """ - del( - self.g0, - self.g1, - self.g2, - ) + for attr in ) + 'g0', + 'g1', + 'g2', + ): + if hasattr(self,attr): + delattr(self,attr) self.calstate = self.braggvectors.calstate pass From bb09061965ad6d36f1873143a67663579a2537d5 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 06:18:46 -0700 Subject: [PATCH 283/362] fit lattice vectors --- py4DSTEM/process/latticevectors/fit.py | 15 +- py4DSTEM/process/latticevectors/index.py | 65 ++++-- py4DSTEM/process/strain.py | 284 +++++++++++++++-------- 3 files changed, 244 insertions(+), 120 deletions(-) diff --git a/py4DSTEM/process/latticevectors/fit.py b/py4DSTEM/process/latticevectors/fit.py index 822ffdea5..fef72aca3 100644 --- a/py4DSTEM/process/latticevectors/fit.py +++ b/py4DSTEM/process/latticevectors/fit.py @@ -104,13 +104,22 @@ def fit_lattice_vectors_all_DPs(braggpeaks, x0=0, y0=0, minNumPeaks=5): # Make RealSlice to contain outputs slicelabels = ('x0','y0','g1x','g1y','g2x','g2y','error','mask') - g1g2_map = RealSlice(data=np.zeros((braggpeaks.shape[0],braggpeaks.shape[1],8)), - slicelabels=slicelabels, name='g1g2_map') + g1g2_map = RealSlice( + data=np.zeros( + (8, braggpeaks.shape[0],braggpeaks.shape[1]) + ), + slicelabels=slicelabels, name='g1g2_map' + ) # Fit lattice vectors for (Rx, Ry) in tqdmnd(braggpeaks.shape[0],braggpeaks.shape[1]): braggpeaks_curr = braggpeaks.get_pointlist(Rx,Ry) - qx0,qy0,g1x,g1y,g2x,g2y,error = fit_lattice_vectors(braggpeaks_curr, x0, y0, minNumPeaks) + qx0,qy0,g1x,g1y,g2x,g2y,error = fit_lattice_vectors( + braggpeaks_curr, + x0, + y0, + minNumPeaks + ) # Store data if g1x is not None: g1g2_map.get_slice('x0').data[Rx,Ry] = qx0 diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index cdf6b00fd..13d41d54c 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -80,6 +80,9 @@ def index_bragg_directions(x0, y0, gx, gy, g1, g2): temp_array = np.zeros([], dtype = coords) bragg_directions = PointList(data = temp_array) bragg_directions.add_data_by_field((gx,gy,h,k)) + mask = np.zeros(bragg_directions['qx'].shape[0]) + mask[0] = 1 + bragg_directions.remove(mask) return h,k, bragg_directions @@ -152,8 +155,14 @@ def generate_lattice(ux,uy,vx,vy,x0,y0,Q_Nx,Q_Ny,h_max=None,k_max=None): return ideal_lattice -def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - qy_shift=0, mask=None): +def add_indices_to_braggvectors( + braggpeaks, + lattice, + maxPeakSpacing, + qx_shift=0, + qy_shift=0, + mask=None + ): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, identify the indices for each peak in the PointListArray braggpeaks. @@ -181,43 +190,51 @@ def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, 'h', 'k', containing the indices of each indexable peak. """ - assert isinstance(braggpeaks,PointListArray) - assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) - assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + # assert isinstance(braggpeaks,BraggVectors) + # assert isinstance(lattice, PointList) + # assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) if mask is None: - mask = np.ones(braggpeaks.shape,dtype=bool) + mask = np.ones(braggpeaks.Rshape,dtype=bool) - assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' + assert mask.shape == braggpeaks.Rshape, 'mask must have same shape as pointlistarray' assert mask.dtype == bool, 'mask must be boolean' - indexed_braggpeaks = braggpeaks.copy() - # add the coordinates if they don't exist - if not ('h' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) - if not ('k' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + coords = [('qx',float),('qy',float),('intensity',float),('h',int),('k',int)] + + indexed_braggpeaks = PointListArray( + dtype = coords, + shape = braggpeaks.Rshape, + ) + + ellipse = braggpeaks.calstate["ellipse"] # loop over all the scan positions for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): if mask[Rx,Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx,Ry) - rm_peak_mask = np.zeros(pl.length,dtype=bool) - - for i in range(pl.length): + pl = braggpeaks.get_vectors( + scan_x=Rx, + scan_y=Ry, + center=True, + ellipse=ellipse, + pixel=False, + rotate=False + ) + + for i in range(pl.data.shape[0]): r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: - pl.data['h'][i] = lattice.data['h'][ind] - pl.data['k'][i] = lattice.data['k'][ind] - else: - rm_peak_mask[i] = True - pl.remove(rm_peak_mask) + indexed_braggpeaks[Rx,Ry].add_data_by_field(( + pl.data['qx'], + pl.data['qy'], + pl.data['intensity'], + lattice.data['h'][ind], + lattice.data['k'][ind] + )) - indexed_braggpeaks.name = braggpeaks.name + "_indexed" return indexed_braggpeaks diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 07dcb91bd..ec10fe5f9 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -6,8 +6,8 @@ from py4DSTEM.data import RealSlice, Data from py4DSTEM.braggvectors import BraggVectors from py4DSTEM.preprocess.utils import get_maxima_2D -from py4DSTEM.visualize import show,add_pointlabels,add_vector - +from py4DSTEM.visualize import show,add_pointlabels,add_vector, add_bragg_index_labels +from py4DSTEM import PointList class StrainMap(RealSlice,Data): """ @@ -62,7 +62,7 @@ def __init__( # if they differ, an error message and instructions for # re-calibration are issued self.calstate = self.braggvectors.calstate - + assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed self.bvm = self.braggvectors.histogram() @@ -87,7 +87,7 @@ def reset_calstate(self): Resets the calibration state. This recomputes the BVM, and removes any computations this StrainMap instance has stored, which will need to be recomputed. """ - for attr in ) + for attr in ( 'g0', 'g1', 'g2', @@ -250,6 +250,7 @@ def choose_lattice_vectors( add_vector(ax2,dg2) # store vectors + self.g = g self.g0 = g0 self.g1 = g1 self.g2 = g2 @@ -263,75 +264,218 @@ def choose_lattice_vectors( return (fig,(ax1,ax2)) else: return + + def fit_lattice_vectors( + self, + x0 = None, + y0 = None, + max_peak_spacing = 2, + mask = None, + plot = True, + vis_params = {}, + returncalc = False, + ): + """ + From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + reciprocal lattice directions. + + Args: + x0 : floagt + x-coord of origin + y0 : float + y-coord of origin + max_peak_spacing: float + Maximum distance from the ideal lattice points + to include a peak for indexing + mask: bool + Boolean mask, same shape as the pointlistarray, indicating which + locations should be indexed. This can be used to index different regions of + the scan with different lattices + plot:bool + plot results if tru + vis_params : dict + additional visualization parameters passed to `show` + returncalc : bool + if True, returns braggdirections, bragg_vectors_indexed, g1g2_map + """ + # check the calstate + assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + if x0 is None: + x0 = self.braggvectors.Qshape[0]/2 + if y0 is None: + y0 = self.braggvectors.Qshape[0]/2 + + #index braggvectors + from py4DSTEM.process.latticevectors import index_bragg_directions + _, _, braggdirections = index_bragg_directions( + x0, + y0, + self.g['x'], + self.g['y'], + self.g1, + self.g2 + ) + self.braggdirections = braggdirections + + if plot: + self.show_bragg_indexing( + self.bvm, + braggdirections = braggdirections, + points = True, + **vis_params, + ) + + #add indicies to braggvectors + from py4DSTEM.process.latticevectors import add_indices_to_braggvectors + + bragg_vectors_indexed = add_indices_to_braggvectors( + self.braggvectors, + self.braggdirections, + maxPeakSpacing = max_peak_spacing, + qx_shift = self.braggvectors.Qshape[0]/2, + qy_shift = self.braggvectors.Qshape[1]/2, + mask = mask + ) + self.bragg_vectors_indexed = bragg_vectors_indexed + #fit bragg vectors + from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs + g1g2_map = fit_lattice_vectors_all_DPs( + self.bragg_vectors_indexed + ) + self.g1g2_map = g1g2_map + if returncalc: + braggdirections, bragg_vectors_indexed, g1g2_map + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): + """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). + """ + fig,ax = show(ar,returnfig=True,**kwargs) + # Add vectors + dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, + 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} + dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, + 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} + add_vector(ax,dg1) + add_vector(ax,dg2) + + if returnfig: + return fig,ax + else: + plt.show() + return + + def show_bragg_indexing( + self, + ar, + braggdirections, + voffset=5, + hoffset=0, + color='w', + size=20, + points=True, + pointcolor='r', + pointsize=50, + returnfig=False, + **kwargs + ): + """ + Shows an array with an overlay describing the Bragg directions + Accepts: + ar (arrray) the image + bragg_directions (PointList) the bragg scattering directions; must have coordinates + 'qx','qy','h', and 'k'. Optionally may also have 'l'. + """ + assert isinstance(braggdirections,PointList) + for k in ('qx','qy','h','k'): + assert k in braggdirections.data.dtype.fields + fig,ax = show(ar,returnfig=True,**kwargs) + d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, + 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} + add_bragg_index_labels(ax,d) + if returnfig: + return fig,ax + else: + plt.show() + return -def index_bragg_directions(x0, y0, gx, gy, g1, g2): - """ - From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - reciprocal lattice directions. - The approach is to solve the matrix equation - ``alpha = beta * M`` - where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, - beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the - h,k indices. - Args: - x0 (float): x-coord of origin - y0 (float): y-coord of origin - gx (1d array): x-coord of the reciprocal lattice vectors - gy (1d array): y-coord of the reciprocal lattice vectors - g1 (2-tuple of floats): g1x,g1y - g2 (2-tuple of floats): g2x,g2y - Returns: - (3-tuple) A 3-tuple containing: - * **h**: *(ndarray of ints)* first index of the bragg directions - * **k**: *(ndarray of ints)* second index of the bragg directions - * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the - indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y - coords 'h' and 'k' contain h and k. - """ - # Get beta, the matrix of lattice vectors - beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - # Get alpha, the matrix of measured bragg angles - alpha = np.vstack([gx-x0,gy-y0]) - # Calculate M, the matrix of peak positions - M = lstsq(beta, alpha, rcond=None)[0].T - M = np.round(M).astype(int) - # Get h,k - h = M[:,0] - k = M[:,1] - # Store in a PointList - coords = [('qx',float),('qy',float),('h',int),('k',int)] - temp_array = np.zeros([], dtype = coords) - bragg_directions = PointList(data = temp_array) - bragg_directions.add_data_by_field((gx,gy,h,k)) - return h,k, bragg_directions +# def index_bragg_directions(x0, y0, gx, gy, g1, g2): +# """ +# From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of +# lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the +# reciprocal lattice directions. +# The approach is to solve the matrix equation +# ``alpha = beta * M`` +# where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, +# beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the +# h,k indices. +# Args: +# x0 (float): x-coord of origin +# y0 (float): y-coord of origin +# gx (1d array): x-coord of the reciprocal lattice vectors +# gy (1d array): y-coord of the reciprocal lattice vectors +# g1 (2-tuple of floats): g1x,g1y +# g2 (2-tuple of floats): g2x,g2y -def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, +# Returns: +# (3-tuple) A 3-tuple containing: + +# * **h**: *(ndarray of ints)* first index of the bragg directions +# * **k**: *(ndarray of ints)* second index of the bragg directions +# * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the +# indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y +# coords 'h' and 'k' contain h and k. +# """ +# # Get beta, the matrix of lattice vectors +# beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + +# # Get alpha, the matrix of measured bragg angles +# alpha = np.vstack([gx-x0,gy-y0]) + +# # Calculate M, the matrix of peak positions +# M = lstsq(beta, alpha, rcond=None)[0].T +# M = np.round(M).astype(int) + +# # Get h,k +# h = M[:,0] +# k = M[:,1] + +# # Store in a PointList +# coords = [('qx',float),('qy',float),('h',int),('k',int)] +# temp_array = np.zeros([], dtype = coords) +# bragg_directions = PointList(data = temp_array) +# bragg_directions.add_data_by_field((gx,gy,h,k)) + +# return h,k, bragg_directions + + + +def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, @@ -407,53 +551,7 @@ def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - - - - def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) - - # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) - - if returnfig: - return fig,ax - else: - plt.show() - return - - - def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, - points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): - """ - Shows an array with an overlay describing the Bragg directions - - Accepts: - ar (arrray) the image - bragg_directions (PointList) the bragg scattering directions; must have coordinates - 'qx','qy','h', and 'k'. Optionally may also have 'l'. - """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) - - if returnfig: - return fig,ax - else: - plt.show() - return + From 4625d3987a5a7a09bb3ade371f6c778412310414 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 06:38:29 -0700 Subject: [PATCH 284/362] small changes --- py4DSTEM/braggvectors/braggvector_methods.py | 6 +++--- py4DSTEM/process/strain.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 53f800ed1..8dd6abe76 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -687,7 +687,7 @@ def index_bragg_directions( - def add_indices_to_braggpeaks( + def add_indices_to_braggvectors( self, maxPeakSpacing, mask = None, @@ -711,9 +711,9 @@ def add_indices_to_braggpeaks( locations should be indexed. This can be used to index different regions of the scan with different lattices """ - from py4DSTEM.process.latticevectors import add_indices_to_braggpeaks + from py4DSTEM.process.latticevectors import add_indices_to_braggvectors - bragg_peaks_indexed = add_indices_to_braggpeaks( + bragg_peaks_indexed = add_indices_to_braggvectors( self.vectors, self.braggdirections, maxPeakSpacing = maxPeakSpacing, diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index ec10fe5f9..76dbbbfb8 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -65,7 +65,7 @@ def __init__( assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed - self.bvm = self.braggvectors.histogram() + self.bvm = self.braggvectors.histogram( mode = 'cal') From 70f0152ee54c548036becd4d35030aaae8a19f72 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 08:38:11 -0700 Subject: [PATCH 285/362] fix calibration for bragg vectors --- py4DSTEM/process/latticevectors/index.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index 13d41d54c..e75ee09e1 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -208,20 +208,10 @@ def add_indices_to_braggvectors( shape = braggpeaks.Rshape, ) - ellipse = braggpeaks.calstate["ellipse"] - # loop over all the scan positions for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): - if mask[Rx,Ry]: - pl = braggpeaks.get_vectors( - scan_x=Rx, - scan_y=Ry, - center=True, - ellipse=ellipse, - pixel=False, - rotate=False - ) - + if mask[Rx,Ry]: + pl = braggpeaks.cal[Rx,Ry] for i in range(pl.data.shape[0]): r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 From 5d973ea202e6931ed851add7ebe305d281065308 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 09:17:24 -0700 Subject: [PATCH 286/362] strain!!! --- py4DSTEM/process/latticevectors/index.py | 6 ++--- py4DSTEM/process/latticevectors/strain.py | 11 +++++--- py4DSTEM/process/strain.py | 33 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index e75ee09e1..189e7f10f 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -218,9 +218,9 @@ def add_indices_to_braggvectors( ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: indexed_braggpeaks[Rx,Ry].add_data_by_field(( - pl.data['qx'], - pl.data['qy'], - pl.data['intensity'], + pl.data['qx'][i], + pl.data['qy'][i], + pl.data['intensity'][i], lattice.data['h'][ind], lattice.data['k'][ind] )) diff --git a/py4DSTEM/process/latticevectors/strain.py b/py4DSTEM/process/latticevectors/strain.py index 50b9bddc9..518f38885 100644 --- a/py4DSTEM/process/latticevectors/strain.py +++ b/py4DSTEM/process/latticevectors/strain.py @@ -71,9 +71,11 @@ def get_strain_from_reference_g1g2(g1g2_map, g1, g2): # Get RealSlice for output storage R_Nx,R_Ny = g1g2_map.get_slice('g1x').shape - strain_map = RealSlice(data=np.zeros((R_Nx,R_Ny,5)), - slicelabels=('e_xx','e_yy','e_xy','theta','mask'), - name='strain_map') + strain_map = RealSlice( + data=np.zeros((5, R_Nx, R_Ny)), + slicelabels=('e_xx','e_yy','e_xy','theta','mask'), + name='strain_map' + ) # Get reference lattice matrix g1x,g1y = g1 @@ -130,7 +132,8 @@ def get_strain_from_reference_region(g1g2_map, mask): Note 1: the strain matrix has been symmetrized, so e_xy and e_yx are identical """ assert isinstance(g1g2_map, RealSlice) - assert np.all([name in g1g2_map.slicelabels for name in ('g1x','g1y','g2x','g2y','mask')]) + assert np.all( + [name in g1g2_map.slicelabels for name in ('g1x','g1y','g2x','g2y','mask')]) assert mask.dtype == bool g1,g2 = get_reference_g1g2(g1g2_map,mask) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 76dbbbfb8..c6a8fe88e 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -352,6 +352,39 @@ def fit_lattice_vectors( if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map + def get_strain( + self, + mask = None, + returncalc = True + ): + """ + + """ + if mask is None: + mask = np.ones(self.g1g2_map.shape, dtype = "bool") + + from py4DSTEM.process.latticevectors import get_strain_from_reference_region + + strainmap_median_g1g2 = get_strain_from_reference_region( + self.g1g2_map, + mask = mask, + ) + + self.strainmap_median_g1g2 = strainmap_median_g1g2 + from py4DSTEM.visualize import show_strain + show_strain( + strainmap_median_g1g2, + vrange_exx = [-2.0, 2.0], + vrange_theta = [-2.0, 2.0], + ticknumber = 3, + axes_plots = (), + bkgrd = False, + figsize = (14,4) + ) + if returncalc: + return strainmap_median_g1g2 + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). """ From 9174f0b1322465624e69529fc9f7b55a8672f01e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Fri, 14 Jul 2023 12:19:37 -0400 Subject: [PATCH 287/362] bugfixes --- py4DSTEM/io/google_drive_downloader.py | 22 +++++++++++----------- test/test_nonnative_io/test_arina.py | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/py4DSTEM/io/google_drive_downloader.py b/py4DSTEM/io/google_drive_downloader.py index 69f4545f9..57a3b298b 100644 --- a/py4DSTEM/io/google_drive_downloader.py +++ b/py4DSTEM/io/google_drive_downloader.py @@ -84,47 +84,47 @@ '1siH80-eRJwG5R6AnU4vkoqGWByrrEz1y' ), 'test_arina_master' : ( - 'STO-STEM_bench_20us_master.h5', + 'STO_STEM_bench_20us_master.h5', '1q_4IjFuWRkw5VM84NhxrNTdIq4563BOC' ), 'test_arina_01' : ( - 'STO-STEM_bench_20us_000001.h5', + 'STO_STEM_bench_20us_data_000001.h5', '1_3Dbm22-hV58iffwK9x-3vqJUsEXZBFQ' ), 'test_arina_02' : ( - 'STO-STEM_bench_20us_000002.h5', + 'STO_STEM_bench_20us_data_000002.h5', '1x29RzHLnCzP0qthLhA1kdlUQ09ENViR8' ), 'test_arina_03' : ( - 'STO-STEM_bench_20us_000003.h5', + 'STO_STEM_bench_20us_data_000003.h5', '1qsbzdEVD8gt4DYKnpwjfoS_Mg4ggObAA' ), 'test_arina_04' : ( - 'STO-STEM_bench_20us_000004.h5', + 'STO_STEM_bench_20us_data_000004.h5', '1Lcswld0Y9fNBk4-__C9iJbc854BuHq-h' ), 'test_arina_05' : ( - 'STO-STEM_bench_20us_000005.h5', + 'STO_STEM_bench_20us_data_000005.h5', '13YTO2ABsTK5nObEr7RjOZYCV3sEk3gt9' ), 'test_arina_06' : ( - 'STO-STEM_bench_20us_000006.h5', + 'STO_STEM_bench_20us_data_000006.h5', '1RywPXt6HRbCvjgjSuYFf60QHWlOPYXwy' ), 'test_arina_07' : ( - 'STO-STEM_bench_20us_000007.h5', + 'STO_STEM_bench_20us_data_000007.h5', '1GRoBecCvAUeSIujzsPywv1vXKSIsNyoT' ), 'test_arina_08' : ( - 'STO-STEM_bench_20us_000008.h5', + 'STO_STEM_bench_20us_data_000008.h5', '1sTFuuvgKbTjZz1lVUfkZbbTDTQmwqhuU' ), 'test_arina_09' : ( - 'STO-STEM_bench_20us_000009.h5', + 'STO_STEM_bench_20us_data_000009.h5', '1JmBiMg16iMVfZ5wz8z_QqcNPVRym1Ezh' ), 'test_arina_10' : ( - 'STO-STEM_bench_20us_000010.h5', + 'STO_STEM_bench_20us_data_000010.h5', '1_90xAfclNVwMWwQ-YKxNNwBbfR1nfHoB' ), } diff --git a/test/test_nonnative_io/test_arina.py b/test/test_nonnative_io/test_arina.py index bf9bf8e73..c27cb8ef5 100644 --- a/test/test_nonnative_io/test_arina.py +++ b/test/test_nonnative_io/test_arina.py @@ -4,7 +4,7 @@ # Set filepaths -filepath = join(py4DSTEM._TESTPATH, "test_arina/STO-STEM_bench_20us_master.h5") +filepath = join(py4DSTEM._TESTPATH, "test_arina/STO_STEM_bench_20us_master.h5") def test_read_arina(): From b0e1ac613968a664294ead264ec1371b9f0db4fd Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 09:28:21 -0700 Subject: [PATCH 288/362] cleaning up formatting --- py4DSTEM/process/strain.py | 468 ++++++++++++++++++++----------------- 1 file changed, 249 insertions(+), 219 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index c6a8fe88e..afe00dba4 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -1,15 +1,17 @@ # Defines the Strain class -import numpy as np -import matplotlib.pyplot as plt from typing import Optional -from py4DSTEM.data import RealSlice, Data + +import matplotlib.pyplot as plt +import numpy as np +from py4DSTEM import PointList from py4DSTEM.braggvectors import BraggVectors +from py4DSTEM.data import Data, RealSlice from py4DSTEM.preprocess.utils import get_maxima_2D -from py4DSTEM.visualize import show,add_pointlabels,add_vector, add_bragg_index_labels -from py4DSTEM import PointList +from py4DSTEM.visualize import add_bragg_index_labels, add_pointlabels, add_vector, show + -class StrainMap(RealSlice,Data): +class StrainMap(RealSlice, Data): """ Stores strain map. @@ -17,33 +19,26 @@ class StrainMap(RealSlice,Data): """ - def __init__( - self, - braggvectors: BraggVectors, - name: Optional[str] = 'strainmap' - ): + def __init__(self, braggvectors: BraggVectors, name: Optional[str] = "strainmap"): """ TODO """ - assert(isinstance(braggvectors,BraggVectors)), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" + assert isinstance( + braggvectors, BraggVectors + ), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" # initialize as a RealSlice RealSlice.__init__( self, - name = name, - data = np.empty(( - 6, - braggvectors.Rshape[0], - braggvectors.Rshape[1], - )), - slicelabels = [ - 'exx', - 'eyy', - 'exy', - 'theta', - 'mask', - 'error' - ] + name=name, + data=np.empty( + ( + 6, + braggvectors.Rshape[0], + braggvectors.Rshape[1], + ) + ), + slicelabels=["exx", "eyy", "exy", "theta", "mask", "error"], ) # set up braggvectors @@ -65,22 +60,24 @@ def __init__( assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed - self.bvm = self.braggvectors.histogram( mode = 'cal') - - + self.bvm = self.braggvectors.histogram(mode="cal") # braggvector properties @property def braggvectors(self): return self._braggvectors + @braggvectors.setter - def braggvectors(self,x): - assert(isinstance(x,BraggVectors)), f".braggvectors must be BraggVectors, not type {type(x)}" - assert(x.calibration.origin is not None), f"braggvectors must have a calibrated origin" + def braggvectors(self, x): + assert isinstance( + x, BraggVectors + ), f".braggvectors must be BraggVectors, not type {type(x)}" + assert ( + x.calibration.origin is not None + ), f"braggvectors must have a calibrated origin" self._braggvectors = x - self._braggvectors.tree(self,force=True) - + self._braggvectors.tree(self, force=True) def reset_calstate(self): """ @@ -88,17 +85,15 @@ def reset_calstate(self): this StrainMap instance has stored, which will need to be recomputed. """ for attr in ( - 'g0', - 'g1', - 'g2', + "g0", + "g1", + "g2", ): - if hasattr(self,attr): - delattr(self,attr) + if hasattr(self, attr): + delattr(self, attr) self.calstate = self.braggvectors.calstate pass - - # Class methods def choose_lattice_vectors( @@ -106,8 +101,8 @@ def choose_lattice_vectors( index_g0, index_g1, index_g2, - subpixel = 'multicorr', - upsample_factor = 16, + subpixel="multicorr", + upsample_factor=16, sigma=0, minAbsoluteIntensity=0, minRelativeIntensity=0, @@ -115,20 +110,20 @@ def choose_lattice_vectors( minSpacing=0, edgeBoundary=1, maxNumPeaks=10, - figsize=(12,6), - c_indices='lightblue', - c0='g', - c1='r', - c2='r', - c_vectors='r', - c_vectorlabels='w', + figsize=(12, 6), + c_indices="lightblue", + c0="g", + c1="r", + c2="r", + c_vectors="r", + c_vectorlabels="w", size_indices=20, width_vectors=1, size_vectorlabels=20, - vis_params = {}, - returncalc = False, + vis_params={}, + returncalc=False, returnfig=False, - ): + ): """ Choose which lattice vectors to use for strain mapping. @@ -195,59 +190,97 @@ def choose_lattice_vectors( (optional) : None or (g0,g1,g2) or (fig,(ax1,ax2)) or both of the latter """ # validate inputs - for i in (index_g0,index_g1,index_g2): - assert isinstance(i,(int,np.integer)), "indices must be integers!" + for i in (index_g0, index_g1, index_g2): + assert isinstance(i, (int, np.integer)), "indices must be integers!" # check the calstate - assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." # find the maxima g = get_maxima_2D( self.bvm.data, - subpixel = subpixel, - upsample_factor = upsample_factor, - sigma = sigma, - minAbsoluteIntensity = minAbsoluteIntensity, - minRelativeIntensity = minRelativeIntensity, - relativeToPeak = relativeToPeak, - minSpacing = minSpacing, - edgeBoundary = edgeBoundary, - maxNumPeaks = maxNumPeaks, + subpixel=subpixel, + upsample_factor=upsample_factor, + sigma=sigma, + minAbsoluteIntensity=minAbsoluteIntensity, + minRelativeIntensity=minRelativeIntensity, + relativeToPeak=relativeToPeak, + minSpacing=minSpacing, + edgeBoundary=edgeBoundary, + maxNumPeaks=maxNumPeaks, ) # get the lattice vectors - gx,gy = g['x'],g['y'] - g0 = gx[index_g0],gy[index_g0] + gx, gy = g["x"], g["y"] + g0 = gx[index_g0], gy[index_g0] g1x = gx[index_g1] - g0[0] g1y = gy[index_g1] - g0[1] g2x = gx[index_g2] - g0[0] g2y = gy[index_g2] - g0[1] - g1,g2 = (g1x,g1y),(g2x,g2y) + g1, g2 = (g1x, g1y), (g2x, g2y) # make the figure - fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) - show(self.bvm.data,figax=(fig,ax1),**vis_params) - show(self.bvm.data,figax=(fig,ax2),**vis_params) + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize) + show(self.bvm.data, figax=(fig, ax1), **vis_params) + show(self.bvm.data, figax=(fig, ax2), **vis_params) # Add indices to left panel - d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} - d0 = {'x':gx[index_g0],'y':gy[index_g0],'size':size_indices, - 'color':c0,'fontweight':'bold','labels':[str(index_g0)]} - d1 = {'x':gx[index_g1],'y':gy[index_g1],'size':size_indices, - 'color':c1,'fontweight':'bold','labels':[str(index_g1)]} - d2 = {'x':gx[index_g2],'y':gy[index_g2],'size':size_indices, - 'color':c2,'fontweight':'bold','labels':[str(index_g2)]} - add_pointlabels(ax1,d) - add_pointlabels(ax1,d0) - add_pointlabels(ax1,d1) - add_pointlabels(ax1,d2) + d = {"x": gx, "y": gy, "size": size_indices, "color": c_indices} + d0 = { + "x": gx[index_g0], + "y": gy[index_g0], + "size": size_indices, + "color": c0, + "fontweight": "bold", + "labels": [str(index_g0)], + } + d1 = { + "x": gx[index_g1], + "y": gy[index_g1], + "size": size_indices, + "color": c1, + "fontweight": "bold", + "labels": [str(index_g1)], + } + d2 = { + "x": gx[index_g2], + "y": gy[index_g2], + "size": size_indices, + "color": c2, + "fontweight": "bold", + "labels": [str(index_g2)], + } + add_pointlabels(ax1, d) + add_pointlabels(ax1, d0) + add_pointlabels(ax1, d1) + add_pointlabels(ax1, d2) # Add vectors to right panel - dg1 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g1[0],'vy':g1[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - dg2 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g2[0],'vy':g2[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - add_vector(ax2,dg1) - add_vector(ax2,dg2) + dg1 = { + "x0": gx[index_g0], + "y0": gy[index_g0], + "vx": g1[0], + "vy": g1[1], + "width": width_vectors, + "color": c_vectors, + "label": r"$g_1$", + "labelsize": size_vectorlabels, + "labelcolor": c_vectorlabels, + } + dg2 = { + "x0": gx[index_g0], + "y0": gy[index_g0], + "vx": g2[0], + "vy": g2[1], + "width": width_vectors, + "color": c_vectors, + "label": r"$g_2$", + "labelsize": size_vectorlabels, + "labelcolor": c_vectorlabels, + } + add_vector(ax2, dg1) + add_vector(ax2, dg2) # store vectors self.g = g @@ -257,24 +290,24 @@ def choose_lattice_vectors( # return if returncalc and returnfig: - return (g0,g1,g2),(fig,(ax1,ax2)) + return (g0, g1, g2), (fig, (ax1, ax2)) elif returncalc: - return (g0,g1,g2) + return (g0, g1, g2) elif returnfig: - return (fig,(ax1,ax2)) + return (fig, (ax1, ax2)) else: return - + def fit_lattice_vectors( self, - x0 = None, - y0 = None, - max_peak_spacing = 2, - mask = None, - plot = True, - vis_params = {}, - returncalc = False, - ): + x0=None, + y0=None, + max_peak_spacing=2, + mask=None, + plot=True, + vis_params={}, + returncalc=False, + ): """ From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the @@ -300,22 +333,20 @@ def fit_lattice_vectors( if True, returns braggdirections, bragg_vectors_indexed, g1g2_map """ # check the calstate - assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." if x0 is None: - x0 = self.braggvectors.Qshape[0]/2 + x0 = self.braggvectors.Qshape[0] / 2 if y0 is None: - y0 = self.braggvectors.Qshape[0]/2 + y0 = self.braggvectors.Qshape[0] / 2 - #index braggvectors + # index braggvectors from py4DSTEM.process.latticevectors import index_bragg_directions + _, _, braggdirections = index_bragg_directions( - x0, - y0, - self.g['x'], - self.g['y'], - self.g1, - self.g2 + x0, y0, self.g["x"], self.g["y"], self.g1, self.g2 ) self.braggdirections = braggdirections @@ -323,104 +354,122 @@ def fit_lattice_vectors( if plot: self.show_bragg_indexing( self.bvm, - braggdirections = braggdirections, - points = True, + braggdirections=braggdirections, + points=True, **vis_params, ) - #add indicies to braggvectors + # add indicies to braggvectors from py4DSTEM.process.latticevectors import add_indices_to_braggvectors bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, self.braggdirections, - maxPeakSpacing = max_peak_spacing, - qx_shift = self.braggvectors.Qshape[0]/2, - qy_shift = self.braggvectors.Qshape[1]/2, - mask = mask + maxPeakSpacing=max_peak_spacing, + qx_shift=self.braggvectors.Qshape[0] / 2, + qy_shift=self.braggvectors.Qshape[1] / 2, + mask=mask, ) self.bragg_vectors_indexed = bragg_vectors_indexed - #fit bragg vectors + # fit bragg vectors from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs - g1g2_map = fit_lattice_vectors_all_DPs( - self.bragg_vectors_indexed - ) + + g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_vectors_indexed) self.g1g2_map = g1g2_map if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map - - def get_strain( - self, - mask = None, - returncalc = True - ): - """ - """ - if mask is None: - mask = np.ones(self.g1g2_map.shape, dtype = "bool") + def get_strain(self, mask=None, returncalc=True): + """ """ + if mask is None: + mask = np.ones(self.g1g2_map.shape, dtype="bool") from py4DSTEM.process.latticevectors import get_strain_from_reference_region strainmap_median_g1g2 = get_strain_from_reference_region( self.g1g2_map, - mask = mask, + mask=mask, ) self.strainmap_median_g1g2 = strainmap_median_g1g2 from py4DSTEM.visualize import show_strain + show_strain( strainmap_median_g1g2, - vrange_exx = [-2.0, 2.0], - vrange_theta = [-2.0, 2.0], - ticknumber = 3, - axes_plots = (), - bkgrd = False, - figsize = (14,4) + vrange_exx=[-2.0, 2.0], + vrange_theta=[-2.0, 2.0], + ticknumber=3, + axes_plots=(), + bkgrd=False, + figsize=(14, 4), ) if returncalc: return strainmap_median_g1g2 - - def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) + def show_lattice_vectors( + ar, + x0, + y0, + g1, + g2, + color="r", + width=1, + labelsize=20, + labelcolor="w", + returnfig=False, + **kwargs, + ): + """Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy).""" + fig, ax = show(ar, returnfig=True, **kwargs) # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) + dg1 = { + "x0": x0, + "y0": y0, + "vx": g1[0], + "vy": g1[1], + "width": width, + "color": color, + "label": r"$g_1$", + "labelsize": labelsize, + "labelcolor": labelcolor, + } + dg2 = { + "x0": x0, + "y0": y0, + "vx": g2[0], + "vy": g2[1], + "width": width, + "color": color, + "label": r"$g_2$", + "labelsize": labelsize, + "labelcolor": labelcolor, + } + add_vector(ax, dg1) + add_vector(ax, dg2) if returnfig: - return fig,ax + return fig, ax else: plt.show() return - - - - def show_bragg_indexing( - self, + self, ar, braggdirections, voffset=5, hoffset=0, - color='w', + color="w", size=20, points=True, - pointcolor='r', + pointcolor="r", pointsize=50, returnfig=False, - **kwargs + **kwargs, ): """ Shows an array with an overlay describing the Bragg directions @@ -430,31 +479,30 @@ def show_bragg_indexing( bragg_directions (PointList) the bragg scattering directions; must have coordinates 'qx','qy','h', and 'k'. Optionally may also have 'l'. """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): + assert isinstance(braggdirections, PointList) + for k in ("qx", "qy", "h", "k"): assert k in braggdirections.data.dtype.fields - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) + fig, ax = show(ar, returnfig=True, **kwargs) + d = { + "braggdirections": braggdirections, + "voffset": voffset, + "hoffset": hoffset, + "color": color, + "size": size, + "points": points, + "pointsize": pointsize, + "pointcolor": pointcolor, + } + add_bragg_index_labels(ax, d) if returnfig: - return fig,ax + return fig, ax else: plt.show() return - - - - - - - - - # def index_bragg_directions(x0, y0, gx, gy, g1, g2): # """ # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of @@ -507,9 +555,9 @@ def show_bragg_indexing( # return h,k, bragg_directions - -def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - qy_shift=0, mask=None): +def add_indices_to_braggvectors( + braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None +): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, identify the indices for each peak in the PointListArray braggpeaks. @@ -537,38 +585,41 @@ def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, 'h', 'k', containing the indices of each indexable peak. """ - assert isinstance(braggpeaks,PointListArray) - assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) + assert isinstance(braggpeaks, PointListArray) + assert np.all( + [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] + ) assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) if mask is None: - mask = np.ones(braggpeaks.shape,dtype=bool) + mask = np.ones(braggpeaks.shape, dtype=bool) - assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' - assert mask.dtype == bool, 'mask must be boolean' + assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" + assert mask.dtype == bool, "mask must be boolean" indexed_braggpeaks = braggpeaks.copy() # add the coordinates if they don't exist - if not ('h' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) - if not ('k' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + if not ("h" in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) + if not ("k" in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) # loop over all the scan positions - for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): - if mask[Rx,Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx,Ry) - rm_peak_mask = np.zeros(pl.length,dtype=bool) + for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): + if mask[Rx, Ry]: + pl = indexed_braggpeaks.get_pointlist(Rx, Ry) + rm_peak_mask = np.zeros(pl.length, dtype=bool) for i in range(pl.length): - r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ - (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 + r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( + pl.data["qy"][i] - lattice.data["qy"] + qy_shift + ) ** 2 ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: - pl.data['h'][i] = lattice.data['h'][ind] - pl.data['k'][i] = lattice.data['k'][ind] + pl.data["h"][i] = lattice.data["h"][ind] + pl.data["k"][i] = lattice.data["k"][ind] else: rm_peak_mask[i] = True pl.remove(rm_peak_mask) @@ -576,40 +627,19 @@ def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, indexed_braggpeaks.name = braggpeaks.name + "_indexed" return indexed_braggpeaks - - - - - - - - - - - - - - - - - - # IO methods # TODO - copy method # read @classmethod - def _get_constructor_args(cls,group): + def _get_constructor_args(cls, group): """ Returns a dictionary of args/values to pass to the class constructor """ ar_constr_args = RealSlice._get_constructor_args(group) args = { - 'data' : ar_constr_args['data'], - 'name' : ar_constr_args['name'], + "data": ar_constr_args["data"], + "name": ar_constr_args["name"], } return args - - - From 0d5ba337f4f6a9702335777317c50ae47837a3c3 Mon Sep 17 00:00:00 2001 From: cophus Date: Fri, 14 Jul 2023 09:32:15 -0700 Subject: [PATCH 289/362] Update defaults for polar fits --- py4DSTEM/process/polar/polar_fits.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index ad418939f..a9da2fe2a 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -7,8 +7,8 @@ def fit_amorphous_ring( im, - center, - radial_range, + center = None, + radial_range = None, coefs = None, show_fit_mask = False, verbose = False, @@ -27,9 +27,11 @@ def fit_amorphous_ring( im: np.array 2D image array to perform fitting on center: np.array - (x,y) center coordinates for fitting mask + (x,y) center coordinates for fitting mask. If not specified + by the user, we will assume the center coordinate is (im.shape-1)/2. radial_range: np.array - (radius_inner, radius_outer) radial range to perform fitting over + (radius_inner, radius_outer) radial range to perform fitting over. + If not specified by the user, we will assume (im.shape[0]/4,im.shape[0]/2). show_fit_mask: bool Set to true to preview the fitting mask and initial guess for the ellipse params verbose: bool @@ -53,6 +55,14 @@ def fit_amorphous_ring( 11 parameter elliptic fit coefficients """ + # Default values + if center is None: + center = np.array(( + (im.shape[0]-1)/2, + (im.shape[1]-1)/2)) + if radial_range is None: + radial_range = (im.shape[0]/4, im.shape[0]/2) + # coordinates xa,ya = np.meshgrid( np.arange(im.shape[0]), From 0609c6ad7d55ea882b9f3ca3f782aea186b384dc Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 10:11:38 -0700 Subject: [PATCH 290/362] working on strain plotting --- py4DSTEM/process/strain.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index afe00dba4..a275f9e6b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -382,7 +382,12 @@ def fit_lattice_vectors( if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map - def get_strain(self, mask=None, returncalc=True): + def get_strain( + self, + mask=None, + returncalc=False, + **kwargs + ): """ """ if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") @@ -395,17 +400,30 @@ def get_strain(self, mask=None, returncalc=True): ) self.strainmap_median_g1g2 = strainmap_median_g1g2 + from py4DSTEM.visualize import show_strain - - show_strain( + figsize = kwargs.pop("figsize", (14, 4)) + vrange_exx = kwargs.pop("vrange_exx", [-2.0, 2.0]) + vrange_theta = kwargs.pop("vrange_theta", [-2.0, 2.0]) + ticknumber = kwargs.pop("ticknumber", 3) + bkgrd = kwargs.pop("bkgrd", False) + axes_plots = kwargs.pop("axes_plots",()) + + fig, ax = show_strain( strainmap_median_g1g2, - vrange_exx=[-2.0, 2.0], - vrange_theta=[-2.0, 2.0], - ticknumber=3, - axes_plots=(), - bkgrd=False, - figsize=(14, 4), + vrange_exx=vrange_exx, + vrange_theta=vrange_theta, + ticknumber=ticknumber, + axes_plots=axes_plots, + bkgrd=bkgrd, + figsize=figsize, + **kwargs, + returnfig = True, ) + + if not np.all(mask == True): + for axs in ax.flatten(): + axs.imshow(mask, alpha = 0.2, cmap = "binary") if returncalc: return strainmap_median_g1g2 From aa75d529352afb88823494d31443066cd2e92dad Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Fri, 14 Jul 2023 14:05:26 -0400 Subject: [PATCH 291/362] autoupdate braggvects calstate --- py4DSTEM/braggvectors/braggvectors.py | 27 +++++++-------------------- py4DSTEM/data/calibration.py | 7 ++++--- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 0bd87bbcb..e3173e466 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -239,6 +239,13 @@ def setcal( print('current calibration state: ', self.calstate) pass + def calibrate(self): + """ + Autoupdate the calstate when relevant calibrations are set + """ + self.setcal() + + # vector getter method @@ -281,26 +288,6 @@ def get_vectors( ) return BVects(ans) - def get_vectors_calibrated( - self, - scan_x, - scan_y, - ): - """ - Returns the calibrated bragg vectors at the specified scan position. - """ - ans = self._v_uncal[scan_x,scan_y].data - ans = self.cal._transform( - data = ans, - cal = self.calibration, - scanxy = (scan_x,scan_y), - center = True, - ellipse = True, - pixel = True, - rotate = True, - ) - return BVects(ans) - # copy def copy(self, name=None): diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index 6077864f3..b5ef200d8 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -64,8 +64,8 @@ class Calibration(Metadata): theta, * p_ellipse, * ellipse, * - QR_rotation_degrees, - QR_flip, + QR_rotation_degrees, * + QR_flip, * QR_rotflip, * probe_semiangle, probe_param, @@ -598,17 +598,18 @@ def ellipse(self,x): # Q/R-space rotation and flip + @call_calibrate def set_QR_rotation_degrees(self,x): self._params['QR_rotation_degrees'] = x def get_QR_rotation_degrees(self): return self._get_value('QR_rotation_degrees') + @call_calibrate def set_QR_flip(self,x): self._params['QR_flip'] = x def get_QR_flip(self): return self._get_value('QR_flip') - @call_calibrate def set_QR_rotflip(self, rot_flip): """ Args: From 61cc2f19c48be531fdb81a120fbb28aaf3eff8bb Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 11:39:16 -0700 Subject: [PATCH 292/362] strain mapping functions --- py4DSTEM/braggvectors/braggvector_methods.py | 350 +++++++++---------- py4DSTEM/process/latticevectors/strain.py | 20 +- py4DSTEM/process/strain.py | 205 ++++++----- 3 files changed, 309 insertions(+), 266 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 8dd6abe76..009f5a193 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -637,187 +637,187 @@ def fit_p_ellipse( # Deprecated?? - def index_bragg_directions( - self, - x0 = None, - y0 = None, - plot = True, - bvm_vis_params = {}, - returncalc = False, - ): - """ - From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - reciprocal lattice directions. - - Args: - x0 (float): x-coord of origin - y0 (float): y-coord of origin - Plot (bool): plot results - """ - - if x0 is None: - x0 = self.Qshape[0]/2 - if y0 is None: - y0 = self.Qshape[0]/2 - - from py4DSTEM.process.latticevectors import index_bragg_directions - _, _, braggdirections = index_bragg_directions( - x0, - y0, - self.g['x'], - self.g['y'], - self.g1, - self.g2 - ) - - self.braggdirections = braggdirections - - if plot: - from py4DSTEM.visualize import show_bragg_indexing - show_bragg_indexing( - self.bvm_centered, - **bvm_vis_params, - braggdirections = braggdirections, - points = True - ) - - if returncalc: - return braggdirections - - - - def add_indices_to_braggvectors( - self, - maxPeakSpacing, - mask = None, - returncalc = False, - ): - """ - Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - identify the indices for each peak in the PointListArray braggpeaks. - Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - indices with the ints (h,k) and indicating whether the peak was successfully indexed - or not with the bool index_mask. If `mask` is specified, only the locations where - mask is True are indexed. - - Args: - maxPeakSpacing (float): Maximum distance from the ideal lattice points - to include a peak for indexing - qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - relative to the `braggpeaks` PointListArray - mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - locations should be indexed. This can be used to index different regions of - the scan with different lattices - """ - from py4DSTEM.process.latticevectors import add_indices_to_braggvectors - - bragg_peaks_indexed = add_indices_to_braggvectors( - self.vectors, - self.braggdirections, - maxPeakSpacing = maxPeakSpacing, - qx_shift = self.Qshape[0]/2, - qy_shift = self.Qshape[1]/2, - ) - - self.bragg_peaks_indexed = bragg_peaks_indexed - - if returncalc: - return bragg_peaks_indexed - - - def fit_lattice_vectors_all_DPs(self, returncalc = False): - """ - Fits lattice vectors g1,g2 to each diffraction pattern in braggpeaks, given some - known (h,k) indexing. - + # def index_bragg_directions( + # self, + # x0 = None, + # y0 = None, + # plot = True, + # bvm_vis_params = {}, + # returncalc = False, + # ): + # """ + # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + # reciprocal lattice directions. + + # Args: + # x0 (float): x-coord of origin + # y0 (float): y-coord of origin + # Plot (bool): plot results + # """ + + # if x0 is None: + # x0 = self.Qshape[0]/2 + # if y0 is None: + # y0 = self.Qshape[0]/2 + + # from py4DSTEM.process.latticevectors import index_bragg_directions + # _, _, braggdirections = index_bragg_directions( + # x0, + # y0, + # self.g['x'], + # self.g['y'], + # self.g1, + # self.g2 + # ) + + # self.braggdirections = braggdirections + + # if plot: + # from py4DSTEM.visualize import show_bragg_indexing + # show_bragg_indexing( + # self.bvm_centered, + # **bvm_vis_params, + # braggdirections = braggdirections, + # points = True + # ) + + # if returncalc: + # return braggdirections + + + + # def add_indices_to_braggvectors( + # self, + # maxPeakSpacing, + # mask = None, + # returncalc = False, + # ): + # """ + # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + # identify the indices for each peak in the PointListArray braggpeaks. + # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + # indices with the ints (h,k) and indicating whether the peak was successfully indexed + # or not with the bool index_mask. If `mask` is specified, only the locations where + # mask is True are indexed. + + # Args: + # maxPeakSpacing (float): Maximum distance from the ideal lattice points + # to include a peak for indexing + # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + # relative to the `braggpeaks` PointListArray + # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + # locations should be indexed. This can be used to index different regions of + # the scan with different lattices + # """ + # from py4DSTEM.process.latticevectors import add_indices_to_braggvectors + + # bragg_peaks_indexed = add_indices_to_braggvectors( + # self.vectors, + # self.braggdirections, + # maxPeakSpacing = maxPeakSpacing, + # qx_shift = self.Qshape[0]/2, + # qy_shift = self.Qshape[1]/2, + # ) + + # self.bragg_peaks_indexed = bragg_peaks_indexed + + # if returncalc: + # return bragg_peaks_indexed + + + # def fit_lattice_vectors_all_DPs(self, returncalc = False): + # """ + # Fits lattice vectors g1,g2 to each diffraction pattern in braggpeaks, given some + # known (h,k) indexing. + + + # """ + + # from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs + # g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_peaks_indexed) + # self.g1g2_map = g1g2_map + # if returncalc: + # return g1g2_map + + # def get_strain_from_reference_region(self, mask, returncalc = False): + # """ + # Gets a strain map from the reference region of real space specified by mask and the + # lattice vector map g1g2_map. + + # Args: + # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions + # wherever mask==True + + # """ + # from py4DSTEM.process.latticevectors import get_strain_from_reference_region + + # strainmap_median_g1g2 = get_strain_from_reference_region( + # self.g1g2_map, + # mask = mask, + # ) + + # self.strainmap_median_g1g2 = strainmap_median_g1g2 + + # if returncalc: + # return strainmap_median_g1g2 + + + # def get_strain_from_reference_g1g2(self, mask, returncalc = False): + # """ + # Gets a strain map from the reference lattice vectors g1,g2 and lattice vector map + # g1g2_map. + + + # Args: + # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions + # wherever mask==True + + # """ + # from py4DSTEM.process.latticevectors import get_reference_g1g2 + # g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + + # from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 + # strainmap_reference_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) - """ - - from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs - g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_peaks_indexed) - self.g1g2_map = g1g2_map - if returncalc: - return g1g2_map - - def get_strain_from_reference_region(self, mask, returncalc = False): - """ - Gets a strain map from the reference region of real space specified by mask and the - lattice vector map g1g2_map. - - Args: - mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - wherever mask==True - - """ - from py4DSTEM.process.latticevectors import get_strain_from_reference_region - - strainmap_median_g1g2 = get_strain_from_reference_region( - self.g1g2_map, - mask = mask, - ) - - self.strainmap_median_g1g2 = strainmap_median_g1g2 - - if returncalc: - return strainmap_median_g1g2 - - - def get_strain_from_reference_g1g2(self, mask, returncalc = False): - """ - Gets a strain map from the reference lattice vectors g1,g2 and lattice vector map - g1g2_map. + # self.strainmap_reference_g1g2 = strainmap_reference_g1g2 + + # if returncalc: + # return strainmap_reference_g1g2 + + # def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, flip_theta = False): + # """ + # Starting from a strain map defined with respect to the xy coordinate system of + # diffraction space, i.e. where exx and eyy are the compression/tension along the Qx + # and Qy directions, respectively, get a strain map defined with respect to some other + # right-handed coordinate system, in which the x-axis is oriented along (xaxis_x, + # xaxis_y). + + # Args: + # g_referencce (tupe): reference coordinate system for xaxis_x and xaxis_y + # """ + # assert mode in ("median","reference") + # if g_reference is None: + # g_reference = np.subtract(self.g1, self.g2) - Args: - mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - wherever mask==True + # from py4DSTEM.process.latticevectors import get_rotated_strain_map - """ - from py4DSTEM.process.latticevectors import get_reference_g1g2 - g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + # if mode == "median": + # strainmap_raw = self.strainmap_median_g1g2 + # elif mode == "reference": + # strainmap_raw = self.strainmap_reference_g1g2 - from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 - strainmap_reference_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + # strainmap = get_rotated_strain_map( + # strainmap_raw, + # xaxis_x = g_reference[0], + # xaxis_y = g_reference[1], + # flip_theta = flip_theta + # ) - self.strainmap_reference_g1g2 = strainmap_reference_g1g2 - - if returncalc: - return strainmap_reference_g1g2 - - def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, flip_theta = False): - """ - Starting from a strain map defined with respect to the xy coordinate system of - diffraction space, i.e. where exx and eyy are the compression/tension along the Qx - and Qy directions, respectively, get a strain map defined with respect to some other - right-handed coordinate system, in which the x-axis is oriented along (xaxis_x, - xaxis_y). - - Args: - g_referencce (tupe): reference coordinate system for xaxis_x and xaxis_y - """ - - assert mode in ("median","reference") - if g_reference is None: - g_reference = np.subtract(self.g1, self.g2) - - from py4DSTEM.process.latticevectors import get_rotated_strain_map - - if mode == "median": - strainmap_raw = self.strainmap_median_g1g2 - elif mode == "reference": - strainmap_raw = self.strainmap_reference_g1g2 - - strainmap = get_rotated_strain_map( - strainmap_raw, - xaxis_x = g_reference[0], - xaxis_y = g_reference[1], - flip_theta = flip_theta - ) - - if returncalc: - return strainmap + # if returncalc: + # return strainmap def mask_in_Q( diff --git a/py4DSTEM/process/latticevectors/strain.py b/py4DSTEM/process/latticevectors/strain.py index 518f38885..7a586bd69 100644 --- a/py4DSTEM/process/latticevectors/strain.py +++ b/py4DSTEM/process/latticevectors/strain.py @@ -172,18 +172,20 @@ def get_rotated_strain_map(unrotated_strain_map, xaxis_x, xaxis_y, flip_theta): sint2 = sint**2 Rx,Ry = unrotated_strain_map.get_slice('e_xx').data.shape - rotated_strain_map = RealSlice(data=np.zeros((Rx,Ry,5)), - slicelabels=['e_xx','e_xy','e_yy','theta','mask'], - name=unrotated_strain_map.name+"_rotated".format(np.degrees(theta))) + rotated_strain_map = RealSlice( + data=np.zeros((5, Rx,Ry)), + slicelabels=['e_xx','e_xy','e_yy','theta','mask'], + name=unrotated_strain_map.name+"_rotated".format(np.degrees(theta)) + ) - rotated_strain_map.data[:,:,0] = cost2*unrotated_strain_map.get_slice('e_xx').data - 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + sint2*unrotated_strain_map.get_slice('e_yy').data - rotated_strain_map.data[:,:,1] = cost*sint*(unrotated_strain_map.get_slice('e_xx').data-unrotated_strain_map.get_slice('e_yy').data) + (cost2-sint2)*unrotated_strain_map.get_slice('e_xy').data - rotated_strain_map.data[:,:,2] = sint2*unrotated_strain_map.get_slice('e_xx').data + 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + cost2*unrotated_strain_map.get_slice('e_yy').data + rotated_strain_map.data[0,:,:] = cost2*unrotated_strain_map.get_slice('e_xx').data - 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + sint2*unrotated_strain_map.get_slice('e_yy').data + rotated_strain_map.data[1,:,:] = cost*sint*(unrotated_strain_map.get_slice('e_xx').data-unrotated_strain_map.get_slice('e_yy').data) + (cost2-sint2)*unrotated_strain_map.get_slice('e_xy').data + rotated_strain_map.data[2,:,:] = sint2*unrotated_strain_map.get_slice('e_xx').data + 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + cost2*unrotated_strain_map.get_slice('e_yy').data if flip_theta == True: - rotated_strain_map.data[:,:,3] = -unrotated_strain_map.get_slice('theta').data + rotated_strain_map.data[3,:,:] = -unrotated_strain_map.get_slice('theta').data else: - rotated_strain_map.data[:,:,3] = unrotated_strain_map.get_slice('theta').data - rotated_strain_map.data[:,:,4] = unrotated_strain_map.get_slice('mask').data + rotated_strain_map.data[3,:,:] = unrotated_strain_map.get_slice('theta').data + rotated_strain_map.data[4,:,:] = unrotated_strain_map.get_slice('mask').data return rotated_strain_map diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index a275f9e6b..0424e92e0 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -385,21 +385,57 @@ def fit_lattice_vectors( def get_strain( self, mask=None, + g_reference=None, + flip_theta=False, returncalc=False, **kwargs ): - """ """ + """ + mask: nd.array (bool) + Use lattice vectors from g1g2_map scan positions + wherever mask==True. If mask is None gets median strain + map from entire field of view. If mask is not None, gets + reference g1 and g2 from region and then calculates strain. + g_reference: nd.array of form [x,y] + G_reference (tupe): reference coordinate system for + xaxis_x and xaxis_y + flip_theta: bool + If True, flips rotation coordinate system + returncal: bool + It True, returns rotated map + """ if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") - from py4DSTEM.process.latticevectors import get_strain_from_reference_region + from py4DSTEM.process.latticevectors import get_strain_from_reference_region - strainmap_median_g1g2 = get_strain_from_reference_region( - self.g1g2_map, - mask=mask, + strainmap_g1g2 = get_strain_from_reference_region( + self.g1g2_map, + mask=mask, + ) + else: + from py4DSTEM.process.latticevectors import get_reference_g1g2 + g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + + from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 + strainmap_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + + self.strainmap_g1g2 = strainmap_g1g2 + + if g_reference is None: + g_reference = np.subtract(self.g1, self.g2) + + print(g_reference) + from py4DSTEM.process.latticevectors import get_rotated_strain_map + + strainmap_rotated = get_rotated_strain_map( + self.strainmap_g1g2, + xaxis_x = g_reference[0], + xaxis_y = g_reference[1], + flip_theta = flip_theta ) - self.strainmap_median_g1g2 = strainmap_median_g1g2 + self.strainmap_rotated = strainmap_rotated from py4DSTEM.visualize import show_strain figsize = kwargs.pop("figsize", (14, 4)) @@ -410,7 +446,7 @@ def get_strain( axes_plots = kwargs.pop("axes_plots",()) fig, ax = show_strain( - strainmap_median_g1g2, + self.strainmap_rotated, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, @@ -422,10 +458,13 @@ def get_strain( ) if not np.all(mask == True): - for axs in ax.flatten(): - axs.imshow(mask, alpha = 0.2, cmap = "binary") + ax[0][0].imshow(mask, alpha = 0.2, cmap = "binary") + ax[0][1].imshow(mask, alpha = 0.2, cmap = "binary") + ax[1][0].imshow(mask, alpha = 0.2, cmap = "binary") + ax[1][1].imshow(mask, alpha = 0.2, cmap = "binary") + if returncalc: - return strainmap_median_g1g2 + return self.strainmap_rotated def show_lattice_vectors( ar, @@ -519,7 +558,9 @@ def show_bragg_indexing( else: plt.show() return - + + # def copy(): + # # TODO - copy method # def index_bragg_directions(x0, y0, gx, gy, g1, g2): # """ @@ -573,81 +614,81 @@ def show_bragg_indexing( # return h,k, bragg_directions -def add_indices_to_braggvectors( - braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None -): - """ - Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - identify the indices for each peak in the PointListArray braggpeaks. - Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - indices with the ints (h,k) and indicating whether the peak was successfully indexed - or not with the bool index_mask. If `mask` is specified, only the locations where - mask is True are indexed. - - Args: - braggpeaks (PointListArray): the braggpeaks to index. Must contain - the coordinates 'qx', 'qy', and 'intensity' - lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. - Must contain the coordinates 'qx', 'qy', 'h', and 'k' - maxPeakSpacing (float): Maximum distance from the ideal lattice points - to include a peak for indexing - qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - relative to the `braggpeaks` PointListArray - mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - locations should be indexed. This can be used to index different regions of - the scan with different lattices - - Returns: - (PointListArray): The original braggpeaks pointlistarray, with new coordinates - 'h', 'k', containing the indices of each indexable peak. - """ +# def add_indices_to_braggvectors( +# braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None +# ): +# """ +# Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, +# identify the indices for each peak in the PointListArray braggpeaks. +# Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus +# three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak +# indices with the ints (h,k) and indicating whether the peak was successfully indexed +# or not with the bool index_mask. If `mask` is specified, only the locations where +# mask is True are indexed. + +# Args: +# braggpeaks (PointListArray): the braggpeaks to index. Must contain +# the coordinates 'qx', 'qy', and 'intensity' +# lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. +# Must contain the coordinates 'qx', 'qy', 'h', and 'k' +# maxPeakSpacing (float): Maximum distance from the ideal lattice points +# to include a peak for indexing +# qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList +# relative to the `braggpeaks` PointListArray +# mask (bool): Boolean mask, same shape as the pointlistarray, indicating which +# locations should be indexed. This can be used to index different regions of +# the scan with different lattices + +# Returns: +# (PointListArray): The original braggpeaks pointlistarray, with new coordinates +# 'h', 'k', containing the indices of each indexable peak. +# """ - assert isinstance(braggpeaks, PointListArray) - assert np.all( - [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] - ) - assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - - if mask is None: - mask = np.ones(braggpeaks.shape, dtype=bool) - - assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" - assert mask.dtype == bool, "mask must be boolean" - - indexed_braggpeaks = braggpeaks.copy() - - # add the coordinates if they don't exist - if not ("h" in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) - if not ("k" in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - - # loop over all the scan positions - for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): - if mask[Rx, Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx, Ry) - rm_peak_mask = np.zeros(pl.length, dtype=bool) - - for i in range(pl.length): - r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( - pl.data["qy"][i] - lattice.data["qy"] + qy_shift - ) ** 2 - ind = np.argmin(r2) - if r2[ind] <= maxPeakSpacing**2: - pl.data["h"][i] = lattice.data["h"][ind] - pl.data["k"][i] = lattice.data["k"][ind] - else: - rm_peak_mask[i] = True - pl.remove(rm_peak_mask) - - indexed_braggpeaks.name = braggpeaks.name + "_indexed" - return indexed_braggpeaks +# assert isinstance(braggpeaks, PointListArray) +# assert np.all( +# [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] +# ) +# assert isinstance(lattice, PointList) +# assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) + +# if mask is None: +# mask = np.ones(braggpeaks.shape, dtype=bool) + +# assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" +# assert mask.dtype == bool, "mask must be boolean" + +# indexed_braggpeaks = braggpeaks.copy() + +# # add the coordinates if they don't exist +# if not ("h" in braggpeaks.dtype.names): +# indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) +# if not ("k" in braggpeaks.dtype.names): +# indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) + +# # loop over all the scan positions +# for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): +# if mask[Rx, Ry]: +# pl = indexed_braggpeaks.get_pointlist(Rx, Ry) +# rm_peak_mask = np.zeros(pl.length, dtype=bool) + +# for i in range(pl.length): +# r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( +# pl.data["qy"][i] - lattice.data["qy"] + qy_shift +# ) ** 2 +# ind = np.argmin(r2) +# if r2[ind] <= maxPeakSpacing**2: +# pl.data["h"][i] = lattice.data["h"][ind] +# pl.data["k"][i] = lattice.data["k"][ind] +# else: +# rm_peak_mask[i] = True +# pl.remove(rm_peak_mask) + +# indexed_braggpeaks.name = braggpeaks.name + "_indexed" +# return indexed_braggpeaks # IO methods - # TODO - copy method + # read @classmethod From 93d20defa4e14390b263d43d4e49bdae129e9bc2 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 11:47:35 -0700 Subject: [PATCH 293/362] strain copy --- py4DSTEM/process/strain.py | 324 +++++++++++++++++++------------------ 1 file changed, 165 insertions(+), 159 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 0424e92e0..3ce202e4b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -25,7 +25,7 @@ def __init__(self, braggvectors: BraggVectors, name: Optional[str] = "strainmap" """ assert isinstance( braggvectors, BraggVectors - ), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" + ), f"braggvectors must be BraggVectors, not type {type(braggvectors)}" # initialize as a RealSlice RealSlice.__init__( @@ -383,27 +383,27 @@ def fit_lattice_vectors( braggdirections, bragg_vectors_indexed, g1g2_map def get_strain( - self, - mask=None, - g_reference=None, - flip_theta=False, - returncalc=False, - **kwargs + self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs ): - """ - mask: nd.array (bool) + """ + mask: nd.array (bool) Use lattice vectors from g1g2_map scan positions wherever mask==True. If mask is None gets median strain - map from entire field of view. If mask is not None, gets + map from entire field of view. If mask is not None, gets reference g1 and g2 from region and then calculates strain. g_reference: nd.array of form [x,y] - G_reference (tupe): reference coordinate system for + G_reference (tupe): reference coordinate system for xaxis_x and xaxis_y flip_theta: bool If True, flips rotation coordinate system returncal: bool It True, returns rotated map """ + # check the calstate + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") @@ -415,38 +415,42 @@ def get_strain( ) else: from py4DSTEM.process.latticevectors import get_reference_g1g2 - g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) - + + g1_ref, g2_ref = get_reference_g1g2(self.g1g2_map, mask) + from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 - strainmap_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + + strainmap_g1g2 = get_strain_from_reference_g1g2( + self.g1g2_map, g1_ref, g2_ref + ) self.strainmap_g1g2 = strainmap_g1g2 if g_reference is None: g_reference = np.subtract(self.g1, self.g2) - print(g_reference) from py4DSTEM.process.latticevectors import get_rotated_strain_map strainmap_rotated = get_rotated_strain_map( self.strainmap_g1g2, - xaxis_x = g_reference[0], - xaxis_y = g_reference[1], - flip_theta = flip_theta + xaxis_x=g_reference[0], + xaxis_y=g_reference[1], + flip_theta=flip_theta, ) - self.strainmap_rotated = strainmap_rotated - + self.data = strainmap_rotated + from py4DSTEM.visualize import show_strain + figsize = kwargs.pop("figsize", (14, 4)) vrange_exx = kwargs.pop("vrange_exx", [-2.0, 2.0]) vrange_theta = kwargs.pop("vrange_theta", [-2.0, 2.0]) ticknumber = kwargs.pop("ticknumber", 3) - bkgrd = kwargs.pop("bkgrd", False) - axes_plots = kwargs.pop("axes_plots",()) + bkgrd = kwargs.pop("bkgrd", False) + axes_plots = kwargs.pop("axes_plots", ()) fig, ax = show_strain( - self.strainmap_rotated, + self.data, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, @@ -454,15 +458,15 @@ def get_strain( bkgrd=bkgrd, figsize=figsize, **kwargs, - returnfig = True, + returnfig=True, ) - if not np.all(mask == True): - ax[0][0].imshow(mask, alpha = 0.2, cmap = "binary") - ax[0][1].imshow(mask, alpha = 0.2, cmap = "binary") - ax[1][0].imshow(mask, alpha = 0.2, cmap = "binary") - ax[1][1].imshow(mask, alpha = 0.2, cmap = "binary") - + if not np.all(mask == True): + ax[0][0].imshow(mask, alpha=0.2, cmap="binary") + ax[0][1].imshow(mask, alpha=0.2, cmap="binary") + ax[1][0].imshow(mask, alpha=0.2, cmap="binary") + ax[1][1].imshow(mask, alpha=0.2, cmap="binary") + if returncalc: return self.strainmap_rotated @@ -558,137 +562,139 @@ def show_bragg_indexing( else: plt.show() return - - # def copy(): - # # TODO - copy method - -# def index_bragg_directions(x0, y0, gx, gy, g1, g2): -# """ -# From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of -# lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the -# reciprocal lattice directions. - -# The approach is to solve the matrix equation -# ``alpha = beta * M`` -# where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, -# beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the -# h,k indices. - -# Args: -# x0 (float): x-coord of origin -# y0 (float): y-coord of origin -# gx (1d array): x-coord of the reciprocal lattice vectors -# gy (1d array): y-coord of the reciprocal lattice vectors -# g1 (2-tuple of floats): g1x,g1y -# g2 (2-tuple of floats): g2x,g2y - -# Returns: -# (3-tuple) A 3-tuple containing: - -# * **h**: *(ndarray of ints)* first index of the bragg directions -# * **k**: *(ndarray of ints)* second index of the bragg directions -# * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the -# indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y -# coords 'h' and 'k' contain h and k. -# """ -# # Get beta, the matrix of lattice vectors -# beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - -# # Get alpha, the matrix of measured bragg angles -# alpha = np.vstack([gx-x0,gy-y0]) - -# # Calculate M, the matrix of peak positions -# M = lstsq(beta, alpha, rcond=None)[0].T -# M = np.round(M).astype(int) - -# # Get h,k -# h = M[:,0] -# k = M[:,1] - -# # Store in a PointList -# coords = [('qx',float),('qy',float),('h',int),('k',int)] -# temp_array = np.zeros([], dtype = coords) -# bragg_directions = PointList(data = temp_array) -# bragg_directions.add_data_by_field((gx,gy,h,k)) - -# return h,k, bragg_directions - - -# def add_indices_to_braggvectors( -# braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None -# ): -# """ -# Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, -# identify the indices for each peak in the PointListArray braggpeaks. -# Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus -# three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak -# indices with the ints (h,k) and indicating whether the peak was successfully indexed -# or not with the bool index_mask. If `mask` is specified, only the locations where -# mask is True are indexed. - -# Args: -# braggpeaks (PointListArray): the braggpeaks to index. Must contain -# the coordinates 'qx', 'qy', and 'intensity' -# lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. -# Must contain the coordinates 'qx', 'qy', 'h', and 'k' -# maxPeakSpacing (float): Maximum distance from the ideal lattice points -# to include a peak for indexing -# qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList -# relative to the `braggpeaks` PointListArray -# mask (bool): Boolean mask, same shape as the pointlistarray, indicating which -# locations should be indexed. This can be used to index different regions of -# the scan with different lattices - -# Returns: -# (PointListArray): The original braggpeaks pointlistarray, with new coordinates -# 'h', 'k', containing the indices of each indexable peak. -# """ - -# assert isinstance(braggpeaks, PointListArray) -# assert np.all( -# [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] -# ) -# assert isinstance(lattice, PointList) -# assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - -# if mask is None: -# mask = np.ones(braggpeaks.shape, dtype=bool) - -# assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" -# assert mask.dtype == bool, "mask must be boolean" - -# indexed_braggpeaks = braggpeaks.copy() - -# # add the coordinates if they don't exist -# if not ("h" in braggpeaks.dtype.names): -# indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) -# if not ("k" in braggpeaks.dtype.names): -# indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - -# # loop over all the scan positions -# for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): -# if mask[Rx, Ry]: -# pl = indexed_braggpeaks.get_pointlist(Rx, Ry) -# rm_peak_mask = np.zeros(pl.length, dtype=bool) - -# for i in range(pl.length): -# r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( -# pl.data["qy"][i] - lattice.data["qy"] + qy_shift -# ) ** 2 -# ind = np.argmin(r2) -# if r2[ind] <= maxPeakSpacing**2: -# pl.data["h"][i] = lattice.data["h"][ind] -# pl.data["k"][i] = lattice.data["k"][ind] -# else: -# rm_peak_mask[i] = True -# pl.remove(rm_peak_mask) - -# indexed_braggpeaks.name = braggpeaks.name + "_indexed" -# return indexed_braggpeaks - # IO methods + def copy(self, name=None): + name = name if name is not None else self.name + "_copy" + strainmap_copy = StrainMap(self.braggvectors) + + for k in self.metadata.keys(): + strainmap_copy.metadata = self.metadata[k].copy() + return strainmap_copy + + # def index_bragg_directions(x0, y0, gx, gy, g1, g2): + # """ + # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + # reciprocal lattice directions. + + # The approach is to solve the matrix equation + # ``alpha = beta * M`` + # where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, + # beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the + # h,k indices. + + # Args: + # x0 (float): x-coord of origin + # y0 (float): y-coord of origin + # gx (1d array): x-coord of the reciprocal lattice vectors + # gy (1d array): y-coord of the reciprocal lattice vectors + # g1 (2-tuple of floats): g1x,g1y + # g2 (2-tuple of floats): g2x,g2y + + # Returns: + # (3-tuple) A 3-tuple containing: + + # * **h**: *(ndarray of ints)* first index of the bragg directions + # * **k**: *(ndarray of ints)* second index of the bragg directions + # * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the + # indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y + # coords 'h' and 'k' contain h and k. + # """ + # # Get beta, the matrix of lattice vectors + # beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + + # # Get alpha, the matrix of measured bragg angles + # alpha = np.vstack([gx-x0,gy-y0]) + + # # Calculate M, the matrix of peak positions + # M = lstsq(beta, alpha, rcond=None)[0].T + # M = np.round(M).astype(int) + + # # Get h,k + # h = M[:,0] + # k = M[:,1] + + # # Store in a PointList + # coords = [('qx',float),('qy',float),('h',int),('k',int)] + # temp_array = np.zeros([], dtype = coords) + # bragg_directions = PointList(data = temp_array) + # bragg_directions.add_data_by_field((gx,gy,h,k)) + + # return h,k, bragg_directions + + # def add_indices_to_braggvectors( + # braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None + # ): + # """ + # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + # identify the indices for each peak in the PointListArray braggpeaks. + # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + # indices with the ints (h,k) and indicating whether the peak was successfully indexed + # or not with the bool index_mask. If `mask` is specified, only the locations where + # mask is True are indexed. + + # Args: + # braggpeaks (PointListArray): the braggpeaks to index. Must contain + # the coordinates 'qx', 'qy', and 'intensity' + # lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. + # Must contain the coordinates 'qx', 'qy', 'h', and 'k' + # maxPeakSpacing (float): Maximum distance from the ideal lattice points + # to include a peak for indexing + # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + # relative to the `braggpeaks` PointListArray + # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + # locations should be indexed. This can be used to index different regions of + # the scan with different lattices + + # Returns: + # (PointListArray): The original braggpeaks pointlistarray, with new coordinates + # 'h', 'k', containing the indices of each indexable peak. + # """ + + # assert isinstance(braggpeaks, PointListArray) + # assert np.all( + # [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] + # ) + # assert isinstance(lattice, PointList) + # assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) + + # if mask is None: + # mask = np.ones(braggpeaks.shape, dtype=bool) + + # assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" + # assert mask.dtype == bool, "mask must be boolean" + + # indexed_braggpeaks = braggpeaks.copy() + + # # add the coordinates if they don't exist + # if not ("h" in braggpeaks.dtype.names): + # indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) + # if not ("k" in braggpeaks.dtype.names): + # indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) + + # # loop over all the scan positions + # for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): + # if mask[Rx, Ry]: + # pl = indexed_braggpeaks.get_pointlist(Rx, Ry) + # rm_peak_mask = np.zeros(pl.length, dtype=bool) + + # for i in range(pl.length): + # r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( + # pl.data["qy"][i] - lattice.data["qy"] + qy_shift + # ) ** 2 + # ind = np.argmin(r2) + # if r2[ind] <= maxPeakSpacing**2: + # pl.data["h"][i] = lattice.data["h"][ind] + # pl.data["k"][i] = lattice.data["k"][ind] + # else: + # rm_peak_mask[i] = True + # pl.remove(rm_peak_mask) + + # indexed_braggpeaks.name = braggpeaks.name + "_indexed" + # return indexed_braggpeaks - + # IO methods # read @classmethod From 3ba12c9ee2ae60c5dd8496e63835c3ca35848192 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 11:57:28 -0700 Subject: [PATCH 294/362] Revert "Merge remote-tracking branch 'origin/dev' into strain_refactor" This reverts commit 6055859961f0ebf4500dcf836c0946ad4e8af4ac, reversing changes made to 93d20defa4e14390b263d43d4e49bdae129e9bc2. --- py4DSTEM/braggvectors/braggvector_methods.py | 57 +- py4DSTEM/braggvectors/braggvectors.py | 17 +- py4DSTEM/braggvectors/probe.py | 1 - py4DSTEM/data/calibration.py | 7 +- py4DSTEM/datacube/datacube.py | 56 +- py4DSTEM/preprocess/preprocess.py | 3 + py4DSTEM/process/calibration/origin.py | 11 +- py4DSTEM/process/diffraction/crystal.py | 15 +- py4DSTEM/process/diffraction/crystal_ACOM.py | 46 +- .../process/diffraction/crystal_calibrate.py | 33 +- py4DSTEM/process/diffraction/crystal_viz.py | 72 +- py4DSTEM/process/diffraction/flowlines.py | 2 +- py4DSTEM/process/fit/fit.py | 226 +-- .../iterative_multislice_ptychography.py | 4 +- py4DSTEM/process/polar/__init__.py | 2 +- py4DSTEM/process/polar/polar_datacube.py | 86 +- py4DSTEM/process/polar/polar_fits.py | 37 +- py4DSTEM/process/polar/polar_peaks.py | 1271 ----------------- py4DSTEM/visualize/show.py | 13 +- 19 files changed, 171 insertions(+), 1788 deletions(-) delete mode 100644 py4DSTEM/process/polar/polar_peaks.py diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 597c7b166..009f5a193 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -186,11 +186,7 @@ def get_virtual_image( mode = None, geometry = None, name = 'bragg_virtual_image', - returncalc = True, - center = True, - ellipse = True, - pixel = True, - rotate = True, + returncalc = True ): ''' Calculates a virtual image based on the values of the Braggvectors @@ -208,22 +204,13 @@ def get_virtual_image( - 'circle', 'circular': nested 2-tuple, ((qx,qy),radius) - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)) - Values can be in pixels or calibrated units. Note that (qx,qy) - can be skipped, which assumes peaks centered at (0,0). - center: bool - Apply calibration - center coordinate. - ellipse: bool - Apply calibration - elliptical correction. - pixel: bool - Apply calibration - pixel size. - rotate: bool - Apply calibration - QR rotation. + All values are in pixels. Note that (qx,qy) can be skipped, which + assumes peaks centered at (0,0) Returns ------- virtual_im : VirtualImage ''' - # parse inputs circle_modes = ['circular','circle'] annulus_modes = ['annular','annulus'] @@ -233,13 +220,13 @@ def get_virtual_image( # set geometry if mode is None: if geometry is None: - qxy_center = None + center = None radial_range = np.array((0,np.inf)) else: if len(geometry[0]) == 0: - qxy_center = None + center = None else: - qxy_center = np.array(geometry[0]) + center = np.array(geometry[0]) if isinstance(geometry[1], int) or isinstance(geometry[1], float): radial_range = np.array((0,geometry[1])) elif len(geometry[1]) == 0: @@ -249,44 +236,30 @@ def get_virtual_image( elif mode == 'circular' or mode == 'circle': radial_range = np.array((0,geometry[1])) if len(geometry[0]) == 0: - qxy_center = None + center = None else: - qxy_center = np.array(geometry[0]) + center = np.array(geometry[0]) elif mode == 'annular' or mode == 'annulus': radial_range = np.array(geometry[1]) if len(geometry[0]) == 0: - qxy_center = None + center = None else: - qxy_center = np.array(geometry[0]) + center = np.array(geometry[0]) # allocate space im_virtual = np.zeros(self.shape) # generate image - for rx,ry in tqdmnd( - self.shape[0], - self.shape[1], - ): - # Get user-specified Bragg vectors - p = self.get_vectors( - rx, - ry, - center = center, - ellipse = ellipse, - pixel = pixel, - rotate = rotate, - ) - + for rx,ry in tqdmnd(self.shape[0],self.shape[1]): + p = self.raw[rx,ry] if p.data.shape[0] > 0: if radial_range is None: im_virtual[rx,ry] = np.sum(p.I) else: - if qxy_center is None: + if center is None: qr = np.hypot(p.qx,p.qy) else: - qr = np.hypot( - p.qx - qxy_center[0], - p.qy - qxy_center[1]) + qr = np.hypot(p.qx - center[0],p.qy - center[1]) sub = np.logical_and( qr >= radial_range[0], qr < radial_range[1]) @@ -311,7 +284,7 @@ def get_virtual_image( } ) # attach to the tree - self.attach(ans) + self.attach( ans) # return if returncalc: diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index e3173e466..14b89fd98 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -65,7 +65,7 @@ def __init__( Rshape, Qshape, name = 'braggvectors', - verbose = False, + verbose = True, calibration = None ): Custom.__init__(self,name=name) @@ -236,16 +236,9 @@ def setcal( "rotate" : rotate, } if self.verbose: - print('current calibration state: ', self.calstate) + print('current calstate: ', self.calstate) pass - def calibrate(self): - """ - Autoupdate the calstate when relevant calibrations are set - """ - self.setcal() - - # vector getter method @@ -257,7 +250,7 @@ def get_vectors( ellipse, pixel, rotate - ): + ): """ Returns the bragg vectors at the specified scan position with the specified calibration state. @@ -275,7 +268,6 @@ def get_vectors( ------- vectors : BVects """ - ans = self._v_uncal[scan_x,scan_y].data ans = self.cal._transform( data = ans, @@ -290,6 +282,7 @@ def get_vectors( # copy + def copy(self, name=None): name = name if name is not None else self.name+"_copy" braggvector_copy = BraggVectors( @@ -302,8 +295,6 @@ def copy(self, name=None): braggvector_copy._v_uncal = self._v_uncal.copy() for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() - # TODO - fix this calibration line? - braggvector_copy.calibration = self.calibration return braggvector_copy diff --git a/py4DSTEM/braggvectors/probe.py b/py4DSTEM/braggvectors/probe.py index 856550616..9195d06bd 100644 --- a/py4DSTEM/braggvectors/probe.py +++ b/py4DSTEM/braggvectors/probe.py @@ -559,7 +559,6 @@ def get_probe_kernel_edge_sigmoid( np.mod(np.arange(Q_Ny) + Q_Ny//2, Q_Ny) - Q_Ny//2, np.mod(np.arange(Q_Nx) + Q_Nx//2, Q_Nx) - Q_Nx//2) qr = np.sqrt(qx**2 + qy**2) - # Calculate sigmoid if type == 'logistic': r0 = 0.5*(ro+ri) diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index b5ef200d8..6077864f3 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -64,8 +64,8 @@ class Calibration(Metadata): theta, * p_ellipse, * ellipse, * - QR_rotation_degrees, * - QR_flip, * + QR_rotation_degrees, + QR_flip, QR_rotflip, * probe_semiangle, probe_param, @@ -598,18 +598,17 @@ def ellipse(self,x): # Q/R-space rotation and flip - @call_calibrate def set_QR_rotation_degrees(self,x): self._params['QR_rotation_degrees'] = x def get_QR_rotation_degrees(self): return self._get_value('QR_rotation_degrees') - @call_calibrate def set_QR_flip(self,x): self._params['QR_flip'] = x def get_QR_flip(self): return self._get_value('QR_flip') + @call_calibrate def set_QR_rotflip(self, rot_flip): """ Args: diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index f56836555..3031b3ff9 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -3,7 +3,7 @@ import numpy as np from scipy.interpolate import interp1d from scipy.ndimage import (binary_opening, binary_dilation, - distance_transform_edt, binary_fill_holes, gaussian_filter1d, gaussian_filter) + distance_transform_edt, binary_fill_holes, gaussian_filter1d) from typing import Optional,Union from emdfile import Array, Metadata, Node, Root, tqdmnd @@ -1015,11 +1015,8 @@ def find_Bragg_disks( def get_beamstop_mask( self, threshold = 0.25, - distance_edge = 2.0, + distance_edge = 4.0, include_edges = True, - sigma = 0, - use_max_dp = False, - scale_radial = None, name = "mask_beamstop", returncalc = True, ): @@ -1034,12 +1031,6 @@ def get_beamstop_mask( distance_edge (float): How many pixels to expand the mask. include_edges (bool): If set to True, edge pixels will be included in the mask. - sigma (float): - Gaussain blur std to apply to image before thresholding. - use_max_dp (bool): - Use the max DP instead of the mean DP. - scale_radial (float): - Scale from center of image by this factor (can help with edge) name (string): Name of the output array. returncalc (bool): Set to true to return the result. @@ -1048,42 +1039,19 @@ def get_beamstop_mask( """ - if scale_radial is not None: - x = np.arange(self.data.shape[2]) * 2.0 / self.data.shape[2] - y = np.arange(self.data.shape[3]) * 2.0 / self.data.shape[3] - ya, xa = np.meshgrid(y - np.mean(y), x - np.mean(x)) - im_scale = 1.0 + np.sqrt(xa**2 + ya**2)*scale_radial - - # Get image for beamstop mask - if use_max_dp: - # if not "dp_mean" in self.tree.keys(): - # self.get_dp_max(); - # im = self.tree["dp_max"].data.astype('float') - if not "dp_max" in self._branch.keys(): - self.get_dp_max(); - im = self.tree("dp_max").data.copy().astype('float') - else: - if not "dp_mean" in self._branch.keys(): - self.get_dp_mean(); - im = self.tree("dp_mean").data.copy() - - # if not "dp_mean" in self.tree.keys(): - # self.get_dp_mean(); - # im = self.tree["dp_mean"].data.astype('float') - - # smooth and scale if needed - if sigma > 0.0: - im = gaussian_filter(im, sigma, mode='nearest') - if scale_radial is not None: - im *= im_scale - - # Calculate beamstop mask - int_sort = np.sort(im.ravel()) + # Calculate dp_mean if needed + if not "dp_mean" in self._branch.keys(): + self.get_dp_mean(); + + # normalized dp_mean + int_sort = np.sort(self.tree("dp_mean").data.ravel()) ind = np.round(np.clip( int_sort.shape[0]*threshold, 0,int_sort.shape[0])).astype('int') intensity_threshold = int_sort[ind] - mask_beamstop = im >= intensity_threshold + + # Use threshold to calculate initial mask + mask_beamstop = self.tree("dp_mean").data >= intensity_threshold # clean up mask mask_beamstop = np.logical_not(binary_fill_holes(np.logical_not(mask_beamstop))) @@ -1120,7 +1088,7 @@ def get_beamstop_mask( ) # Add to tree - self.tree(x) + self.attach( mask_beamstop ) # return if returncalc: diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 162b9a32d..c156c228e 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -265,6 +265,8 @@ def bin_data_diffraction( # set dim vectors Qpixsize = datacube.calibration.get_Q_pixel_size() * bin_factor Qpixunits = datacube.calibration.get_Q_pixel_units() + + datacube.set_dim( 2, [0,Qpixsize], @@ -281,6 +283,7 @@ def bin_data_diffraction( # set calibration pixel size datacube.calibration.set_Q_pixel_size(Qpixsize) + # return return datacube diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 8821b43d0..0b27f5a85 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -73,12 +73,11 @@ def fit_origin( ): """ Fits the position of the origin of diffraction space to a plane or parabola, - given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, - optionally masked by the Boolean array `mask`. The 2D data arrays may be - passed directly as a 2-tuple to the arg `data`, or, if `data` is either a - DataCube or Calibration instance, they will be retreived automatically. If a - DataCube or Calibration are passed, fitted origin and residuals are stored - there directly. + given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, optionally + masked by the Boolean array `mask`. The 2D data arrays may be passed directly as + a 2-tuple to the arg `data`, or, if `data` is either a DataCube or Calibration + instance, they will be retreived automatically. If a DataCube or Calibration are + passed, fitted origin and residuals are stored there directly. Args: data (2-tuple of 2d arrays): the measured origin position (qx0,qy0) diff --git a/py4DSTEM/process/diffraction/crystal.py b/py4DSTEM/process/diffraction/crystal.py index 3be87eb25..228602692 100644 --- a/py4DSTEM/process/diffraction/crystal.py +++ b/py4DSTEM/process/diffraction/crystal.py @@ -898,19 +898,12 @@ def calculate_bragg_peak_histogram( k = np.arange(k_min, k_max + k_step, k_step) k_num = k.shape[0] - # concatenate all peaks + # experimental data histogram bigpl = np.concatenate( [ - bragg_peaks.get_vectors( - rx, - ry, - center = True, - ellipse = True, - pixel = True, - rotate = True, - ).data - for rx in range(bragg_peaks.shape[0]) - for ry in range(bragg_peaks.shape[1]) + bragg_peaks.cal[i, j].data + for i in range(bragg_peaks.shape[0]) + for j in range(bragg_peaks.shape[1]) ] ) qr = np.sqrt(bigpl["qx"] ** 2 + bigpl["qy"] ** 2) diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index 686de7847..4d02dcb0b 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -8,8 +8,6 @@ from py4DSTEM.process.diffraction.utils import Orientation, OrientationMap, axisEqual3D from py4DSTEM.process.utils import electron_wavelength_angstrom -from warnings import warn - from numpy.linalg import lstsq try: import cupy as cp @@ -769,18 +767,6 @@ def match_orientations( num_x=bragg_peaks_array.shape[0], num_y=bragg_peaks_array.shape[1], num_matches=num_matches_return) - - #check cal state - if bragg_peaks_array.calstate['ellipse'] == False: - ellipse = False - warn('Warning: bragg peaks not elliptically calibrated') - else: - ellipse = True - if bragg_peaks_array.calstate['rotate'] == False: - rotate = False - warn('bragg peaks not rotationally calibrated') - else: - rotate = True for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -788,17 +774,9 @@ def match_orientations( unit=" PointList", disable=not progress_bar, ): - vectors = bragg_peaks_array.get_vectors( - scan_x=rx, - scan_y=ry, - center=True, - ellipse=ellipse, - pixel=True, - rotate=rotate - ) orientation = self.match_single_pattern( - bragg_peaks=vectors, + bragg_peaks_array.cal[rx, ry], num_matches_return=num_matches_return, min_number_peaks=min_number_peaks, inversion_symmetry=inversion_symmetry, @@ -1661,18 +1639,6 @@ def calculate_strain( corr_kernel_size = self.orientation_kernel_size radius_max_2 = corr_kernel_size**2 - #check cal state - if bragg_peaks_array.calstate['ellipse'] == False: - ellipse = False - warn('bragg peaks not elliptically calibrated') - else: - ellipse = True - if bragg_peaks_array.calstate['rotate'] == False: - rotate = False - warn('bragg peaks not rotationally calibrated') - else: - rotate = True - # Loop over all probe positions for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -1681,14 +1647,7 @@ def calculate_strain( disable=not progress_bar, ): # Get bragg peaks from experiment and reference - p = bragg_peaks_array.get_vectors( - scan_x=rx, - scan_y=ry, - center=True, - ellipse=ellipse, - pixel=True, - rotate=rotate - ) + p = bragg_peaks_array.cal[rx,ry] if p.data.shape[0] >= min_num_peaks: p_ref = self.generate_diffraction_pattern( @@ -2112,3 +2071,4 @@ def symmetry_reduce_directions( # "-3m": ["fiber", [0, 0, 1], [90.0, 60.0]], # "-3m": ["fiber", [0, 0, 1], [180.0, 30.0]], + diff --git a/py4DSTEM/process/diffraction/crystal_calibrate.py b/py4DSTEM/process/diffraction/crystal_calibrate.py index d4be6abce..2d08cd03c 100644 --- a/py4DSTEM/process/diffraction/crystal_calibrate.py +++ b/py4DSTEM/process/diffraction/crystal_calibrate.py @@ -24,7 +24,7 @@ def calibrate_pixel_size( k_step = 0.002, k_broadening = 0.002, fit_all_intensities = True, - set_calibration_in_place = False, + set_calibration = True, verbose = True, plot_result = False, figsize: Union[list, tuple, np.ndarray] = (12, 6), @@ -60,13 +60,8 @@ def calibrate_pixel_size( figsize (list, tuple, np.ndarray): Figure size of the plot. returnfig (bool): Return handles figure and axis - Returns - _______ - - - - fig, ax: handles, optional - Figure and axis handles, if returnfig=True. + Returns: + fig, ax (handles): Optional figure and axis handles, if returnfig=True. """ @@ -117,21 +112,17 @@ def fit_profile(k, *coefs): # Get the answer pix_size_prev = bragg_peaks.calibration.get_Q_pixel_size() - pixel_size_new = pix_size_prev / scale_pixel_size + ans = pix_size_prev / scale_pixel_size - # if requested, apply calibrations in place - if set_calibration_in_place: - bragg_peaks.calibration.set_Q_pixel_size( pixel_size_new ) + # if requested, apply calibrations + if set_calibration: + bragg_peaks.calibration.set_Q_pixel_size( ans ) bragg_peaks.calibration.set_Q_pixel_units('A^-1') + bragg_peaks.setcal() - # Output calibrated Bragg peaks - bragg_peaks_cali = bragg_peaks.copy() - bragg_peaks_cali.calibration.set_Q_pixel_size( pixel_size_new ) - bragg_peaks_cali.calibration.set_Q_pixel_units('A^-1') - - # Output pixel size + # Output if verbose: - print(f"Calibrated pixel size = {np.round(pixel_size_new, decimals=8)} A^-1") + print(f"Calibrated pixel size = {np.round(ans, decimals=8)} A^-1") # Plotting if plot_result: @@ -172,9 +163,9 @@ def fit_profile(k, *coefs): # return if returnfig and plot_result: - return bragg_peaks_cali, (fig,ax) + return ans, (fig,ax) else: - return bragg_peaks_cali + return ans diff --git a/py4DSTEM/process/diffraction/crystal_viz.py b/py4DSTEM/process/diffraction/crystal_viz.py index 9395682a0..9c1f5b667 100644 --- a/py4DSTEM/process/diffraction/crystal_viz.py +++ b/py4DSTEM/process/diffraction/crystal_viz.py @@ -296,48 +296,30 @@ def plot_scattering_intensity( bragg_k_power=0.0, bragg_intensity_power=1.0, bragg_k_broadening=0.005, - figsize: Union[list, tuple, np.ndarray] = (10, 4), + figsize: Union[list, tuple, np.ndarray] = (12, 6), returnfig: bool = False, ): """ 1D plot of the structure factors - Parameters - -------- - - k_min: float - min k value for profile range. - k_max: float - max k value for profile range. - k_step: float - Step size of k in profile range. - k_broadening: float - Broadening of simulated pattern. - k_power_scale: float - Scale SF intensities by k**k_power_scale. - int_power_scale: float - Scale SF intensities**int_power_scale. - int_scale: float - Scale output profile by this value. - remove_origin: bool - Remove origin from plot. - bragg_peaks: BraggVectors - Passed in bragg_peaks for comparison with simulated pattern. - bragg_k_power: float - bragg_peaks scaled by k**bragg_k_power. - bragg_intensity_power: float - bragg_peaks scaled by intensities**bragg_intensity_power. - bragg_k_broadening: float - Broadening applied to bragg_peaks. - figsize: list, tuple, np.ndarray - Figure size for plot. - returnfig (bool): - Return figure and axes handles if this is True. - - Returns - -------- - fig, ax (optional) - figure and axes handles + Args: + k_min (float): min k value for profile range. + k_max (float): max k value for profile range. + k_step (float): step size of k in profile range. + k_broadening (float): Broadening of simulated pattern. + k_power_scale (float): Scale SF intensities by k**k_power_scale. + int_power_scale (float): Scale SF intensities**int_power_scale. + int_scale (float): Scale output profile by this value. + remove_origin (bool): Remove origin from plot. + bragg_peaks (BraggVectors): Passed in bragg_peaks for comparison with simulated pattern. + bragg_k_power (float): bragg_peaks scaled by k**bragg_k_power. + bragg_intensity_power (float): bragg_peaks scaled by intensities**bragg_intensity_power. + bragg_k_broadening float): Broadening applied to bragg_peaks. + figsize (list, tuple, np.ndarray): Figure size for plot. + returnfig (bool): Return figure and axes handles if this is True. + + Returns: + fig, ax (optional) figure and axes handles """ # k coordinates @@ -363,16 +345,9 @@ def plot_scattering_intensity( # concatenate all peaks bigpl = np.concatenate( [ - bragg_peaks.get_vectors( - rx, - ry, - center = True, - ellipse = True, - pixel = True, - rotate = True, - ).data - for rx in range(bragg_peaks.shape[0]) - for ry in range(bragg_peaks.shape[1]) + bragg_peaks.cal[i, j].data + for i in range(bragg_peaks.shape[0]) + for j in range(bragg_peaks.shape[1]) ] ) @@ -928,9 +903,6 @@ def plot_diffraction_pattern( ax.set_ylabel("$q_x$ [Å$^{-1}$]") if plot_range_kx_ky is not None: - plot_range_kx_ky = np.array(plot_range_kx_ky) - if plot_range_kx_ky.ndim == 0: - plot_range_kx_ky = np.array((plot_range_kx_ky,plot_range_kx_ky)) ax.set_xlim((-plot_range_kx_ky[0], plot_range_kx_ky[0])) ax.set_ylim((-plot_range_kx_ky[1], plot_range_kx_ky[1])) else: diff --git a/py4DSTEM/process/diffraction/flowlines.py b/py4DSTEM/process/diffraction/flowlines.py index 27d4f9381..c2fa224fa 100644 --- a/py4DSTEM/process/diffraction/flowlines.py +++ b/py4DSTEM/process/diffraction/flowlines.py @@ -15,7 +15,7 @@ def make_orientation_histogram( - bragg_peaks: PointListArray = None, + bragg_peaks: PointList = None, radial_ranges: np.ndarray = None, orientation_map = None, orientation_ind: int = 0, diff --git a/py4DSTEM/process/fit/fit.py b/py4DSTEM/process/fit/fit.py index 9abb713f7..e3bb4d86e 100644 --- a/py4DSTEM/process/fit/fit.py +++ b/py4DSTEM/process/fit/fit.py @@ -29,49 +29,44 @@ def fit_1D_gaussian(xdata,ydata,xmin,xmax): A,mu,sigma = scale*popt[0],popt[1],popt[2] return A,mu,sigma -def fit_2D( - function, - data, - data_mask=None, - popt=None, - robust=False, - robust_steps=3, - robust_thresh=2, - ): +def fit_2D(function, data, data_mask=None, popt=None, + robust=False, robust_steps=3, robust_thresh=2): """ - Performs a 2D fit. - - TODO: make returning the mask optional - - Parameters - ---------- - function : callable - Some `function( xy, **p)` where `xy` is a length 2 vector (1D np array) - specifying the pixel position (x,y), and `p` is the function parameters - data : ndarray - Some 2D array of any shape (n,m) - data_mask : None or boolean array of shape (n,m), optional - If specified, fits only the pixels in `data` where this array is True - popt : dict - Initial guess at the parameters `p` of `function`. Note that positions - in pixels (i.e. the xy positions) are linearly scaled to the space [0,1] - robust : bool - Toggles robust fitting, which iteratively rejects outlier data points - which have a root-mean-square error beyond `robust_thresh` - robust_steps : int - The number of robust fitting iterations to perform - robust_thresh : int - The robust fitting cutoff + Performs a 2D fit, where the fit function takes its first input in the form of a + length 2 vector (ndarray) of (x,y) positions, followed by the remaining parameters, + and the data to fit takes the form of an (n,m) shaped array. Robust fitting can be + enabled to iteratively reject outlier data points, which have a root-mean-square + error beyond the user-specified threshold. + + Args: + function: First input should be a length 2 array xy, where (xy[0],xy[1]) are the + (x,y) coordinates + data: Data to fit, in an (n,m) shaped ndarray + data_mask: Optional parameter. If specified, must be a boolean array of the same + shape as data, specifying which elements of data to use in the fit + return_ar: Optional parameter. If False, only the fit parameters and covariance + matrix are returned. If True, return an array of the same shape as data with + the fit values. Defaults to True + popt: Optional parameter for input. If specified, should be a tuple of initial + guesses for the fit parameters. + robust: Optional parameter. If set to True, fit will be repeated with outliers + removed. + robust_steps: Optional parameter. Number of robust iterations performed after + initial fit. + robust_thresh: Optional parameter. Threshold for including points, in units of + root-mean-square (standard deviations) error of the predicted values after + fitting. Returns: - (popt,pcov,fit_at, mask) : 4-tuple - The optimal fit parameters, the fitting covariance matrix, the - the fit array with the returned `popt` params, and the mask + (3-tuple) A 3-tuple containing: + + * **popt**: optimal fit parameters to function + * **pcov**: the covariance matrix + * **fit_ar**: optional. If return_ar==True, fit_ar is returned, and is an + array of the same shape as data, containing the fit values """ - # get shape shape = data.shape shape1D = [1,np.prod(shape)] - # x and y coordinates normalized from 0 to 1 x,y = np.linspace(0, 1, shape[0]),np.linspace(0, 1, shape[1]) ry,rx = np.meshgrid(y,x) @@ -83,10 +78,8 @@ def fit_2D( if robust==False: robust_steps=0 - # least squares fitting + # least squares fitting - 1st iteration for k in range(robust_steps+1): - - # in 1st iteration, set up params and mask if k == 0: if popt is None: popt = np.zeros((1,len(signature(function).parameters)-1)) @@ -94,26 +87,21 @@ def fit_2D( mask = data_mask else: mask = np.ones(shape,dtype=bool) - - # otherwise, get fitting error and add high error pixels to mask else: - fit_mean_square_error = ( - function(xy,*popt).reshape(shape) - data)**2 - _mask = fit_mean_square_error > np.mean( - fit_mean_square_error) * robust_thresh**2 - mask[_mask] == False + fit_mean_square_error = (function(xy,*popt).reshape(shape) - data)**2 + mask = fit_mean_square_error <= np.mean(fit_mean_square_error) * robust_thresh**2 + # include user-specified mask if provided + if data_mask is not None: + mask[data_mask==False] = False # perform fitting - popt, pcov = curve_fit( - function, - np.vstack(( - rx_1D[mask.reshape(shape1D)], - ry_1D[mask.reshape(shape1D)])), + popt, pcov = curve_fit(function, + np.vstack((rx_1D[mask.reshape(shape1D)],ry_1D[mask.reshape(shape1D)])), data[mask], p0=popt) fit_ar = function(xy,*popt).reshape(shape) - return popt, pcov, fit_ar, mask + return popt, pcov, fit_ar # Functions for fitting @@ -139,137 +127,5 @@ def bezier_two(xy, c00, c01, c02, c10, c11, c12, c20, c21, c22): c12*2*(1-xy[0])*xy[0] * (xy[1]**2) + \ c22 *(xy[0]**2) * (xy[1]**2) -def polar_gaussian_2D( - tq, - I0, - mu_t, - mu_q, - sigma_t, - sigma_q, - C, - ): - # unpack position - t,q = tq - # set theta value to its closest periodic reflection to mu_t - #t = np.square(t-mu_t) - #t2 = np.min(np.vstack([t,1-t])) - t2 = np.square(t-mu_t) - return \ - I0 * np.exp( - - ( t2/(2*sigma_t**2) + \ - (q-mu_q)**2/(2*sigma_q**2) ) ) + C - - -def polar_twofold_gaussian_2D( - tq, - I0, - mu_t, - mu_q, - sigma_t, - sigma_q, - ): - - # unpack position - t,q = tq - - # theta periodicity - dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 - - # output intensity - return I0 * np.exp( - (dt**2 / (-2.0*sigma_t**2)) + \ - ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) - -def polar_twofold_gaussian_2D_background( - tq, - I0, - mu_t, - mu_q, - sigma_t, - sigma_q, - C, - ): - - # unpack position - t,q = tq - - # theta periodicity - dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 - - # output intensity - return C + I0 * np.exp( - (dt**2 / (-2.0*sigma_t**2)) + \ - ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) - - -def fit_2D_polar_gaussian( - data, - mask = None, - p0 = None, - robust = False, - robust_steps = 3, - robust_thresh = 2, - constant_background = False, - ): - """ - - NOTE - this cannot work without using pixel coordinates - something is wrong in the workflow. - - - Fits a 2D gaussian to the pixels in `data` which are set to True in `mask`. - - The gaussian is anisotropic and oriented along (t,q), centered at - (mu_t,mu_q), has standard deviations (sigma_t,sigma_q), maximum of I0, - and an optional constant offset of C, and is periodic in t. - - f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) - or - f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + C - - Parameters - ---------- - data : 2d array - the data to fit - p0 : 6-tuple - initial guess at fit parameters, (I0,mu_x,mu_y,sigma_x_sigma_y,C) - mask : 2d boolean array - ignore pixels where mask is False - robust : bool - toggle robust fitting - robust_steps : int - number of robust fit iterations - robust_thresh : number - the robust fitting threshold - constant_background : bool - whether or not to include constant background - - Returns - ------- - (popt,pcov,fit_ar) : 3-tuple - the optimal fit parameters, the covariance matrix, and the fit array - """ - - if constant_background: - return fit_2D( - polar_twofold_gaussian_2D_background, - data = data, - data_mask = mask, - popt = p0, - robust = robust, - robust_steps = robust_steps, - robust_thresh = robust_thresh - ) - else: - return fit_2D( - polar_twofold_gaussian_2D, - data = data, - data_mask = mask, - popt = p0, - robust = robust, - robust_steps = robust_steps, - robust_thresh = robust_thresh - ) - - diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 8be875b15..1e9bd2cbb 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -974,7 +974,7 @@ def _gradient_descent_adjoint( ) # back-transmit - exit_waves *= xp.conj(obj) #/ xp.abs(obj) ** 2 + exit_waves *= xp.conj(obj) / xp.abs(obj) ** 2 if s > 0: # back-propagate @@ -1076,7 +1076,7 @@ def _projection_sets_adjoint( ) # back-transmit - exit_waves_copy *= xp.conj(obj) # / xp.abs(obj) ** 2 + exit_waves_copy *= xp.conj(obj) / xp.abs(obj) ** 2 if s > 0: # back-propagate diff --git a/py4DSTEM/process/polar/__init__.py b/py4DSTEM/process/polar/__init__.py index ddf0a9e50..741e0c610 100644 --- a/py4DSTEM/process/polar/__init__.py +++ b/py4DSTEM/process/polar/__init__.py @@ -1,3 +1,3 @@ from py4DSTEM.process.polar.polar_datacube import PolarDatacube from py4DSTEM.process.polar.polar_fits import fit_amorphous_ring, plot_amorphous_ring -from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks, refine_peaks, plot_radial_peaks, plot_radial_background, make_orientation_histogram + diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 3f3db0eca..f1d4277fb 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -21,7 +21,7 @@ def __init__( mask = None, mask_thresh = 0.25, ellipse = True, - two_fold_symmetry = False, + two_fold_rotation = False, ): """ Parameters @@ -29,15 +29,14 @@ def __init__( datacube : DataCube The datacube in cartesian coordinates qmin : number - Minumum radius of the polar transformation, in pixels + Minumum radius of the polar transformation qmax : number or None - Maximum radius of the polar transformation, in pixels + Maximum radius of the polar transformation qstep : number - Width of radial bins, in pixels + Width of radial bins n_annular : integer Number of bins in the annular direction. Bins will each - have a width of 360/n_annular, or 180/n_annular if - two_fold_rotation is set to True, in degrees + have a width of 360/num_annular_bins, in degrees qscale : number or None Radial scaling power to apply to polar transform mask : boolean array @@ -50,10 +49,9 @@ def __init__( performs an elliptic transform iff elliptic calibrations are available. two_fold_rotation : bool - Setting to True computes the transform mod(theta,pi), i.e. assumes - all patterns possess two-fold rotation (Friedel symmetry). The - output angular range in this case becomes [0, pi) as opposed to the - default of [0,2*pi). + Setting to True computes the transform mod(theta,pi), i.e. assumes all patterns + posess two-fold rotation (Friedel symmetry). The output angular range in this case + becomes [0, pi) as opposed to the default of [0,2*pi). """ # attach datacube @@ -70,12 +68,17 @@ def __init__( # setup sampling + # annular range, depending on if polar transform spans pi or 2*pi + if two_fold_rotation: + self._annular_range = np.pi + else: + self._annular_range = 2.0 * np.pi + # polar self._qscale = qscale if qmax is None: qmax = np.min(self._datacube.Qshape) / np.sqrt(2) - self._n_annular = n_annular - self.two_fold_symmetry = two_fold_symmetry #implicitly calls set_annular_bins + self.set_annular_bins(n_annular) self.set_radial_bins(qmin,qmax,qstep) # cartesian @@ -99,16 +102,6 @@ def __init__( plot_FEM_global, calculate_FEM_local, ) - from py4DSTEM.process.polar.polar_peaks import ( - find_peaks_single_pattern, - find_peaks, - refine_peaks_local, - refine_peaks, - plot_radial_peaks, - plot_radial_background, - model_radial_background, - make_orientation_histogram, - ) # sampling methods + properties @@ -128,7 +121,6 @@ def set_radial_bins( self._qstep ) self.qscale = self._qscale - self._radial_step = self._datacube.calibration.get_Q_pixel_size() * self._qstep self.set_polar_shape() @property @@ -184,18 +176,6 @@ def annular_bins(self): @property def annular_step(self): return self._annular_step - @property - def two_fold_symmetry(self): - return self._two_fold_symmetry - @two_fold_symmetry.setter - def two_fold_symmetry(self,x): - assert(isinstance(x,bool)), f"two_fold_symmetry must be boolean, not type {type(x)}" - self._two_fold_symmetry = x - if x: - self._annular_range = np.pi - else: - self._annular_range = 2 * np.pi - self.set_annular_bins(self._n_annular) @property def n_annular(self): @@ -215,22 +195,8 @@ def set_polar_shape(self): # set KDE params self._annular_bin_step = 1 / (self._annular_step * (self.radial_bins + self.qstep * 0.5)) self._sigma_KDE = self._annular_bin_step * 0.5 - # set array indices - self._annular_indices = np.arange(self.polar_shape[0]).astype(int) - self._radial_indices = np.arange(self.polar_shape[1]).astype(int) - # coordinate grid properties - @property - def tt(self): - return self._annular_bins - @property - def tt_deg(self): - return self._annular_bins * 180/np.pi - @property - def qq(self): - return self.radial_bins * self.calibration.get_Q_pixel_size() - # scaling property @@ -476,7 +442,6 @@ def _transform( ) return ans elif returnval == 'nan': - ans[mask_bool] = np.nan return ans elif returnval == 'all': return ans, ans_norm, norm_array, mask_bool @@ -507,7 +472,7 @@ def _transform_array( # get polar coords rr = np.sqrt(x**2 + y**2) tt = np.mod( - np.arctan2(y, x), + np.arctan2(y, x) - np.pi/2, self._polarcube._annular_range) # elliptical @@ -515,12 +480,21 @@ def _transform_array( # unpack ellipse a,b,theta = ellipse - # Get polar coords - xc = x*np.cos(theta) + y*np.sin(theta) - yc = (y*np.cos(theta) - x*np.sin(theta))*(a/b) - rr = (b/a) * np.hypot(xc,yc) + # transformation matrix (elliptic cartesian -> circular cartesian) + A = (a/b)*np.cos(theta) + B = -np.sin(theta) + C = (a/b)*np.sin(theta) + D = np.cos(theta) + det = 1 / (A*D - B*C) + + # get circular cartesian coords + xc = x*D - y*B + yc = -x*C + y*A + + # get polar coords + rr = det * np.hypot(xc,yc) tt = np.mod( - np.arctan2(yc,xc) + theta, + np.arctan2(yc,xc) - np.pi/2, self._polarcube._annular_range) # transform to bin sampling diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index 9d7e50290..ad418939f 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -7,14 +7,13 @@ def fit_amorphous_ring( im, - center = None, - radial_range = None, + center, + radial_range, coefs = None, - mask_dp = None, show_fit_mask = False, verbose = False, plot_result = True, - plot_log_scale = False, + plot_log_scale = True, plot_int_scale = (-3,3), figsize = (8,8), return_all_coefs = True, @@ -28,15 +27,9 @@ def fit_amorphous_ring( im: np.array 2D image array to perform fitting on center: np.array - (x,y) center coordinates for fitting mask. If not specified - by the user, we will assume the center coordinate is (im.shape-1)/2. + (x,y) center coordinates for fitting mask radial_range: np.array - (radius_inner, radius_outer) radial range to perform fitting over. - If not specified by the user, we will assume (im.shape[0]/4,im.shape[0]/2). - coefs: np.array (optional) - Array containing initial fitting coefficients for the amorphous fit. - mask_dp: np.array - Dark field mask for fitting, in addition to the radial range specified above. + (radius_inner, radius_outer) radial range to perform fitting over show_fit_mask: bool Set to true to preview the fitting mask and initial guess for the ellipse params verbose: bool @@ -60,14 +53,6 @@ def fit_amorphous_ring( 11 parameter elliptic fit coefficients """ - # Default values - if center is None: - center = np.array(( - (im.shape[0]-1)/2, - (im.shape[1]-1)/2)) - if radial_range is None: - radial_range = (im.shape[0]/4, im.shape[0]/2) - # coordinates xa,ya = np.meshgrid( np.arange(im.shape[0]), @@ -81,9 +66,6 @@ def fit_amorphous_ring( ra2 >= radial_range[0]**2, ra2 <= radial_range[1]**2, ) - if mask_dp is not None: - # Logical AND the radial mask with the user-provided mask - mask = np.logical_and(mask, mask_dp) vals = im[mask] basis = np.vstack((xa[mask],ya[mask])) @@ -136,11 +118,9 @@ def fit_amorphous_ring( int_range = ( int_med + plot_int_scale[0]*int_std, int_med + plot_int_scale[1]*int_std) - im_plot = np.tile( - np.clip( - (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), - 0,1), - (1,1,3)) + im_plot = np.tile(np.clip( + (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), + 0,1),(1,1,3)) else: int_med = np.median(vals) @@ -367,3 +347,4 @@ def amorphous_model(basis, *coefs): int_model[sub] += int12*np.exp(dr2[sub]/(-2*sigma2**2)) return int_model + diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py deleted file mode 100644 index 3f367b398..000000000 --- a/py4DSTEM/process/polar/polar_peaks.py +++ /dev/null @@ -1,1271 +0,0 @@ - -import numpy as np -import matplotlib.pyplot as plt - -from scipy.ndimage import gaussian_filter, gaussian_filter1d -from scipy.signal import peak_prominences -from skimage.feature import peak_local_max -from scipy.optimize import curve_fit -import warnings - -# from emdfile import tqdmnd, PointList, PointListArray -from py4DSTEM import tqdmnd, PointList, PointListArray -from py4DSTEM.process.fit import polar_twofold_gaussian_2D, polar_twofold_gaussian_2D_background - -def find_peaks_single_pattern( - self, - x, - y, - mask = None, - bragg_peaks = None, - bragg_mask_radius = None, - sigma_annular_deg = 10.0, - sigma_radial_px = 3.0, - sigma_annular_deg_max = None, - radial_background_subtract = True, - radial_background_thresh = 0.25, - num_peaks_max = 100, - threshold_abs = 1.0, - threshold_prom_annular = None, - threshold_prom_radial = None, - remove_masked_peaks = False, - scale_sigma_annular = 0.5, - scale_sigma_radial = 0.25, - return_background = False, - plot_result = True, - plot_power_scale = 1.0, - plot_scale_size = 100.0, - returnfig = False, - ): - """ - Peak detection function for polar transformations. - - Parameters - -------- - x: int - x index of diffraction pattern - y: int - y index of diffraction pattern - mask: np.array - Boolean mask in Cartesian space, to filter detected peaks. - bragg_peaks: py4DSTEM.BraggVectors - Set of Bragg peaks used to generated a mask in Cartesian space, to filter detected peaks - sigma_annular_deg: float - smoothing along the annular direction in degrees, periodic - sigma_radial_px: float - smoothing along the radial direction in pixels, not periodic - sigma_annular_deg_max: float - Specify this value for the max annular sigma. Peaks larger than this will be split - into multiple peaks, depending on the ratio. - radial_background_subtract: bool - If true, subtract radial background estimate - radial_background_thresh: float - Relative order of sorted values to use as background estimate. - Setting to 0.5 is equivalent to median, 0.0 is min value. - - Returns - -------- - - """ - - # if needed, generate mask from Bragg peaks - if bragg_peaks is not None: - mask_bragg = self._datacube.get_braggmask( - bragg_peaks, - x, - y, - radius = bragg_mask_radius, - ) - if mask is None: - mask = mask_bragg - else: - mask = np.logical_or(mask, mask_bragg) - - - # Convert sigma values into units of bins - sigma_annular = np.deg2rad(sigma_annular_deg) / self.annular_step - sigma_radial = sigma_radial_px / self.qstep - - # Get transformed image and normalization array - im_polar, im_polar_norm, norm_array, mask_bool = self.transform( - self._datacube.data[x,y], - mask = mask, - returnval = 'all_zeros', - ) - # Change sign convention of mask - mask_bool = np.logical_not(mask_bool) - - # Background subtraction - if radial_background_subtract: - sig_bg = np.zeros(im_polar.shape[1]) - for a0 in range(im_polar.shape[1]): - if np.any(mask_bool[:,a0]): - vals = np.sort(im_polar[mask_bool[:,a0],a0]) - ind = np.round(radial_background_thresh * (vals.shape[0]-1)).astype('int') - sig_bg[a0] = vals[ind] - sig_bg_mask = np.sum(mask_bool, axis=0) >= (im_polar.shape[0]//2) - im_polar = np.maximum(im_polar - sig_bg[None,:], 0) - - # apply smoothing and normalization - im_polar_sm = gaussian_filter( - im_polar * norm_array, - sigma = (sigma_annular, sigma_radial), - mode = ('wrap', 'nearest'), - ) - im_mask = gaussian_filter( - norm_array, - sigma = (sigma_annular, sigma_radial), - mode = ('wrap', 'nearest'), - ) - sub = im_mask > 0.001 * np.max(im_mask) - im_polar_sm[sub] /= im_mask[sub] - - # Find local maxima - peaks = peak_local_max( - im_polar_sm, - num_peaks = num_peaks_max, - threshold_abs = threshold_abs, - ) - - # check if peaks should be removed from the polar transformation mask - if remove_masked_peaks: - peaks = np.delete( - peaks, - mask_bool[peaks[:,0],peaks[:,1]] == False, - axis = 0, - ) - - # peak intensity - peaks_int = im_polar_sm[peaks[:,0],peaks[:,1]] - - # Estimate prominance of peaks, and their size in units of pixels - peaks_prom = np.zeros((peaks.shape[0],4)) - annular_ind_center = np.atleast_1d(np.array(im_polar_sm.shape[0]//2).astype('int')) - for a0 in range(peaks.shape[0]): - - # annular - trace_annular = np.roll( - np.squeeze(im_polar_sm[:,peaks[a0,1]]), - annular_ind_center - peaks[a0,0]) - p_annular = peak_prominences( - trace_annular, - annular_ind_center, - ) - sigma_annular = scale_sigma_annular * np.maximum( - annular_ind_center - p_annular[1], - p_annular[2] - annular_ind_center) - - # radial - trace_radial = im_polar_sm[peaks[a0,0],:] - p_radial = peak_prominences( - trace_radial, - np.atleast_1d(peaks[a0,1]), - ) - sigma_radial = scale_sigma_radial * np.maximum( - peaks[a0,1] - p_radial[1], - p_radial[2] - peaks[a0,1]) - - # output - peaks_prom[a0,0] = p_annular[0] - peaks_prom[a0,1] = sigma_annular[0] - peaks_prom[a0,2] = p_radial[0] - peaks_prom[a0,3] = sigma_radial[0] - - # if needed, remove peaks using prominance criteria - if threshold_prom_annular is not None: - remove = peaks_prom[:,0] < threshold_prom_annular - peaks = np.delete( - peaks, - remove, - axis = 0, - ) - peaks_int = np.delete( - peaks_int, - remove, - ) - peaks_prom = np.delete( - peaks_prom, - remove, - axis = 0, - ) - if threshold_prom_radial is not None: - remove = peaks_prom[:,2] < threshold_prom_radial - peaks = np.delete( - peaks, - remove, - axis = 0, - ) - peaks_int = np.delete( - peaks_int, - remove, - ) - peaks_prom = np.delete( - peaks_prom, - remove, - axis = 0, - ) - - # combine peaks into one array - peaks_all = np.column_stack((peaks, peaks_int, peaks_prom)) - - # Split peaks into multiple peaks if they have sigma values larger than user-specified threshold - if sigma_annular_deg_max is not None: - peaks_new = np.zeros((0,peaks_all.shape[1])) - for a0 in range(peaks_all.shape[0]): - if peaks_all[a0,4] >= (1.5*sigma_annular_deg_max): - num = np.round(peaks_all[a0,4] / sigma_annular_deg_max) - sigma_annular_new = peaks_all[a0,4] / num - - v = np.arange(num) - v -= np.mean(v) - t_new = np.mod(peaks_all[a0,0] + 2*v*sigma_annular_new, - self._n_annular) - - for a1 in range(num.astype('int')): - peaks_new = np.vstack(( - peaks_new, - np.array(( - t_new[a1], - peaks_all[a0,1], - peaks_all[a0,2], - peaks_all[a0,3], - sigma_annular_new, - peaks_all[a0,5], - peaks_all[a0,6], - )), - )) - else: - peaks_new = np.vstack(( - peaks_new, - peaks_all[a0,:] - )) - peaks_all = peaks_new - - - # Output data as a pointlist - peaks_polar = PointList( - peaks_all.ravel().view([ - ('qt', float), - ('qr', float), - ('intensity', float), - ('prom_annular', float), - ('sigma_annular', float), - ('prom_radial', float), - ('sigma_radial', float), - ]), - name = 'peaks_polar') - - - if plot_result: - # init - im_plot = im_polar.copy() - im_plot = np.maximum(im_plot, 0) ** plot_power_scale - - t = np.linspace(0,2*np.pi,180+1) - ct = np.cos(t) - st = np.sin(t) - - - fig,ax = plt.subplots(figsize=(12,6)) - - ax.imshow( - im_plot, - cmap = 'gray', - ) - - # peaks - ax.scatter( - peaks_polar['qr'], - peaks_polar['qt'], - s = peaks_polar['intensity'] * plot_scale_size, - marker='o', - color = (1,0,0), - ) - for a0 in range(peaks_polar.data.shape[0]): - ax.plot( - peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], - peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0], - linewidth = 1, - color = 'r', - ) - if peaks_polar['qt'][a0] - peaks_polar['sigma_annular'][a0] < 0: - ax.plot( - peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], - peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0] + im_plot.shape[0], - linewidth = 1, - color = 'r', - ) - if peaks_polar['qt'][a0] + peaks_polar['sigma_annular'][a0] > im_plot.shape[0]: - ax.plot( - peaks_polar['qr'][a0] + st * peaks_polar['sigma_radial'][a0], - peaks_polar['qt'][a0] + ct * peaks_polar['sigma_annular'][a0] - im_plot.shape[0], - linewidth = 1, - color = 'r', - ) - - # plot appearance - ax.set_xlim((0,im_plot.shape[1]-1)) - ax.set_ylim((im_plot.shape[0]-1,0)) - - if returnfig and plot_result: - if return_background: - return peaks_polar, sig_bg, sig_bg_mask, fig, ax - else: - return peaks_polar, fig, ax - else: - if return_background: - return peaks_polar, sig_bg, sig_bg_mask - else: - return peaks_polar - - -def find_peaks( - self, - mask = None, - bragg_peaks = None, - bragg_mask_radius = None, - sigma_annular_deg = 10.0, - sigma_radial_px = 3.0, - sigma_annular_deg_max = None, - radial_background_subtract = True, - radial_background_thresh = 0.25, - num_peaks_max = 100, - threshold_abs = 1.0, - threshold_prom_annular = None, - threshold_prom_radial = None, - remove_masked_peaks = False, - scale_sigma_annular = 0.5, - scale_sigma_radial = 0.25, - progress_bar = True, - ): - """ - Peak detection function for polar transformations. Loop through all probe positions, - find peaks. Store the peak positions and background signals. - - Parameters - -------- - sigma_annular_deg: float - smoothing along the annular direction in degrees, periodic - sigma_radial_px: float - smoothing along the radial direction in pixels, not periodic - - Returns - -------- - - """ - - # init - self.bragg_peaks = bragg_peaks - self.bragg_mask_radius = bragg_mask_radius - self.peaks = PointListArray( - dtype = [ - ('qt', ' min_num_pixels_fit: - try: - # perform fitting - p0, pcov = curve_fit( - polar_twofold_gaussian_2D, - tq[:,mask_peak.ravel()], - im_polar[mask_peak], - p0 = p0, - # bounds = bounds, - ) - - # Output parameters - self.peaks[rx,ry]['intensity'][a0] = p0[0] - self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step - self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step - self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step - self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step - - except: - pass - - else: - # initial parameters - p0 = [ - p['intensity'][a0], - p['qt'][a0] * t_step, - p['qr'][a0] * q_step, - p['sigma_annular'][a0] * t_step, - p['sigma_radial'][a0] * q_step, - 0, - ] - - # Mask around peak for fitting - dt = np.mod(tt - p0[1] + np.pi/2, np.pi) - np.pi/2 - mask_peak = np.logical_and(mask_bool, - dt**2/(fit_range_sigma_annular*p0[3])**2 \ - + (qq-p0[2])**2/(fit_range_sigma_radial*p0[4])**2 <= 1) - - if np.sum(mask_peak) > min_num_pixels_fit: - try: - # perform fitting - p0, pcov = curve_fit( - polar_twofold_gaussian_2D_background, - tq[:,mask_peak.ravel()], - im_polar[mask_peak], - p0 = p0, - # bounds = bounds, - ) - - # Output parameters - self.peaks[rx,ry]['intensity'][a0] = p0[0] - self.peaks[rx,ry]['qt'][a0] = p0[1] / t_step - self.peaks[rx,ry]['qr'][a0] = p0[2] / q_step - self.peaks[rx,ry]['sigma_annular'][a0] = p0[3] / t_step - self.peaks[rx,ry]['sigma_radial'][a0] = p0[4] / q_step - - except: - pass - - -def plot_radial_peaks( - self, - q_pixel_units = False, - qmin = None, - qmax = None, - qstep = None, - label_y_axis = False, - figsize = (8,4), - returnfig = False, - ): - """ - Calculate and plot the total peak signal as a function of the radial coordinate. - - """ - - # Get all peak data - vects = np.concatenate( - [self.peaks[i,j].data for i in range(self._datacube.Rshape[0]) for j in range(self._datacube.Rshape[1])]) - if q_pixel_units: - qr = vects['qr'] - else: - qr = (vects['qr'] + self.qmin) * self._radial_step - intensity = vects['intensity'] - - # bins - if qmin is None: - qmin = self.qq[0] - if qmax is None: - qmax = self.qq[-1] - if qstep is None: - qstep = self.qq[1] - self.qq[0] - q_bins = np.arange(qmin,qmax,qstep) - q_num = q_bins.shape[0] - if q_pixel_units: - q_bins /= self._radial_step - - # histogram - q_ind = (qr - q_bins[0]) / (q_bins[1] - q_bins[0]) - qf = np.floor(q_ind).astype("int") - dq = q_ind - qf - - sub = np.logical_and(qf >= 0, qf < q_num) - int_peaks = np.bincount( - np.floor(q_ind[sub]).astype("int"), - weights=(1 - dq[sub]) * intensity[sub], - minlength=q_num, - ) - sub = np.logical_and(q_ind >= -1, q_ind < q_num - 1) - int_peaks += np.bincount( - np.floor(q_ind[sub] + 1).astype("int"), - weights=dq[sub] * intensity[sub], - minlength=q_num, - ) - - - # plotting - fig,ax = plt.subplots(figsize = figsize) - ax.plot( - q_bins, - int_peaks, - color = 'r', - linewidth = 2, - ) - ax.set_xlim((q_bins[0],q_bins[-1])) - if q_pixel_units: - ax.set_xlabel( - 'Scattering Angle (pixels)', - fontsize = 14, - ) - else: - ax.set_xlabel( - 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', - fontsize = 14, - ) - ax.set_ylabel( - 'Total Peak Signal', - fontsize = 14, - ) - if not label_y_axis: - ax.tick_params( - left = False, - labelleft = False) - - if returnfig: - return fig,ax - - -def model_radial_background( - self, - ring_position = None, - ring_sigma = None, - ring_int = None, - refine_model = True, - plot_result = True, - ): - """ - User provided radial background model, of the form: - - int = int_const - + int_0 * exp( - q**2 / (2*s0**2) ) - + int_1 * exp( - (q - q_1)**2 / (2*s1**2) ) - + ... - + int_n * exp( - (q - q_n)**2 / (2*sn**2) ) - - where n is the number of amorphous halos / rings included in the fit. - - """ - - # Get mean radial background and mask - self.background_radial_mean = np.sum( - self.background_radial * self.background_radial_mask, - axis=(0,1)) - background_radial_mean_norm = np.sum( - self.background_radial_mask, - axis=(0,1)) - self.background_mask = \ - background_radial_mean_norm > (np.max(background_radial_mean_norm)*0.05) - self.background_radial_mean[self.background_mask] \ - /= background_radial_mean_norm[self.background_mask] - self.background_radial_mean[np.logical_not(self.background_mask)] = 0 - - # init - if ring_position is not None: - ring_position = np.atleast_1d(np.array(ring_position)) - num_rings = ring_position.shape[0] - else: - num_rings = 0 - self.background_coefs = np.zeros(3 + 3*num_rings) - - if ring_sigma is None: - ring_sigma = np.atleast_1d(np.ones(num_rings)) \ - * self.polar_shape[1] * 0.05 * self._radial_step - else: - ring_sigma = np.atleast_1d(np.array(ring_sigma)) - - # Background model initial parameters - int_const = np.min(self.background_radial_mean) - int_0 = np.max(self.background_radial_mean) - int_const - sigma_0 = self.polar_shape[1] * 0.25 * self._radial_step - self.background_coefs[0] = int_const - self.background_coefs[1] = int_0 - self.background_coefs[2] = sigma_0 - - # Additional Gaussians - if ring_int is None: - # Estimate peak intensities - sig_0 = int_const + int_0*np.exp(self.qq**2/(-2*sigma_0**2)) - sig_peaks = np.maximum(self.background_radial_mean - sig_0, 0.0) - - ring_int = np.atleast_1d(np.zeros(num_rings)) - for a0 in range(num_rings): - ind = np.argmin(np.abs(self.qq - ring_position[a0])) - ring_int[a0] = sig_peaks[ind] - - else: - ring_int = np.atleast_1d(np.array(ring_int)) - for a0 in range(num_rings): - self.background_coefs[3*a0+3] = ring_int[a0] - self.background_coefs[3*a0+4] = ring_sigma[a0] - self.background_coefs[3*a0+5] = ring_position[a0] - - # Create background model - def background_model(q, *coefs): - coefs = np.squeeze(np.array(coefs)) - num_rings = np.round((coefs.shape[0] - 3)/3).astype('int') - - sig = np.ones(q.shape[0])*coefs[0] - sig += coefs[1]*np.exp(q**2/(-2*coefs[2]**2)) - - for a0 in range(num_rings): - sig += coefs[3*a0+3]*np.exp( - (q-coefs[3*a0+5])**2 / (-2*coefs[3*a0+4]**2)) - - return sig - - self.background_model = background_model - - # Refine background model coefficients - if refine_model: - self.background_coefs = curve_fit( - self.background_model, - self.qq[self.background_mask], - self.background_radial_mean[self.background_mask], - p0 = self.background_coefs, - xtol = 1e-12, - # bounds = (lb,ub), - )[0] - - # plotting - if plot_result: - self.plot_radial_background( - q_pixel_units = False, - plot_background_model = True, - ) - - - -def refine_peaks( - self, - mask = None, - # reset_fits_to_init_positions = False, - scale_sigma_estimate = 0.5, - min_num_pixels_fit = 10, - progress_bar = True, - ): - """ - Use global fitting model for all images. Requires an background model - specified with self.model_radial_background(). - - TODO: add fitting reset - add min number pixels condition - track any failed fitting points, output as a boolean array - - Parameters - -------- - mask: np.array - Mask image to apply to all images - radial_background_subtract: bool - Subtract radial background before fitting - reset_fits_to_init_positions: bool - Use the initial peak parameters for fitting - scale_sigma_estimate: float - Factor to reduce sigma of peaks by, to prevent fit from running away. - min_num_pixels_fit: int - Minimum number of pixels to perform fitting - progress_bar: bool - Enable progress bar - - Returns - -------- - - """ - - # coordinate scaling - t_step = self._annular_step - q_step = self._radial_step - - # Background model params - num_rings = np.round((self.background_coefs.shape[0]-3)/3).astype('int') - - # basis - qq,tt = np.meshgrid( - self.qq, - self.tt, - ) - basis = np.zeros((qq.size,3)) - basis[:,0] = tt.ravel() - basis[:,1] = qq.ravel() - basis[:,2] = num_rings - - # init - self.peaks_refine = PointListArray( - dtype = [ - ('qt', 'float'), - ('qr', 'float'), - ('intensity', 'float'), - ('sigma_annular', 'float'), - ('sigma_radial', 'float')], - shape = self._datacube.Rshape, - name = 'peaks_polardata_refined', - ) - self.background_refine = np.zeros(( - self._datacube.Rshape[0], - self._datacube.Rshape[1], - np.round(3*num_rings+3).astype('int'), - )) - - - # Main loop over probe positions - for rx, ry in tqdmnd( - self._datacube.shape[0], - self._datacube.shape[1], - desc="Refining peaks ", - unit=" probe positions", - disable=not progress_bar): - - # Get transformed image and normalization array - im_polar, im_polar_norm, norm_array, mask_bool = self.transform( - self._datacube.data[rx,ry], - mask = mask, - returnval = 'all_zeros', - ) - # Change sign convention of mask - mask_bool = np.logical_not(mask_bool) - - # Get initial peaks, in dimensioned units - p = self.peaks[rx,ry] - qt = p.data['qt'] * t_step - qr = (p.data['qr'] + self.qmin) * q_step - int_peaks = p.data['intensity'] - s_annular = p.data['sigma_annular'] * t_step - s_radial = p.data['sigma_radial'] * q_step - num_peaks = p['qt'].shape[0] - - # unified coefficients - # Note we sharpen sigma estimate for refinement - coefs_all = np.hstack(( - self.background_coefs, - qt, - qr, - int_peaks, - s_annular * scale_sigma_estimate, - s_radial * scale_sigma_estimate, - )) - - # Construct fitting model - def fit_image(basis, *coefs): - coefs = np.squeeze(np.array(coefs)) - - num_rings = np.round(basis[0,2]).astype('int') - num_peaks = np.round((coefs.shape[0] - (3*num_rings+3))/5).astype('int') - - coefs_bg = coefs[:(3*num_rings+3)] - coefs_peaks = coefs[(3*num_rings+3):] - - - # Background - sig = self.background_model( - basis[:,1], - coefs_bg) - - # add peaks - for a0 in range(num_peaks): - dt = np.mod(basis[:,0] - coefs_peaks[num_peaks*0+a0] + np.pi/2, np.pi) - np.pi/2 - dq = basis[:,1] - coefs_peaks[num_peaks*1+a0] - - sig += coefs_peaks[num_peaks*2+a0] \ - * np.exp( - dt**2 / (-2*coefs_peaks[num_peaks*3+a0]**2) + \ - dq**2 / (-2*coefs_peaks[num_peaks*4+a0]**2)) - - return sig - - # refine fitting model - try: - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - coefs_all = curve_fit( - fit_image, - basis[mask_bool.ravel(),:], - im_polar[mask_bool], - p0 = coefs_all, - xtol = 1e-12, - # bounds = (lb,ub), - )[0] - - # Output refined peak parameters - coefs_peaks = np.reshape( - coefs_all[(3*num_rings+3):], - (5,num_peaks)).T - self.peaks_refine[rx,ry] = PointList( - coefs_peaks.ravel().view([ - ('qt', float), - ('qr', float), - ('intensity', float), - ('sigma_annular', float), - ('sigma_radial', float), - ]), - name = 'peaks_polar') - except: - # if fitting has failed, we will output the mean background signal, - # but none of the peaks. - pass - - # Output refined parameters for background - coefs_bg = coefs_all[:(3*num_rings+3)] - self.background_refine[rx,ry] = coefs_bg - - - # # Testing - # im_fit = np.reshape( - # fit_image(basis,coefs_all), - # self.polar_shape) - - - # fig,ax = plt.subplots(figsize=(8,6)) - # ax.imshow( - # np.vstack(( - # im_polar, - # im_fit, - # )), - # cmap = 'turbo', - # ) - - -def plot_radial_background( - self, - q_pixel_units = False, - label_y_axis = False, - plot_background_model = False, - figsize = (8,4), - returnfig = False, - ): - """ - Calculate and plot the mean background signal, background standard deviation. - - """ - - # mean - self.background_radial_mean = np.sum( - self.background_radial * self.background_radial_mask, - axis=(0,1)) - background_radial_mean_norm = np.sum( - self.background_radial_mask, - axis=(0,1)) - self.background_mask = \ - background_radial_mean_norm > (np.max(background_radial_mean_norm)*0.05) - self.background_radial_mean[self.background_mask] \ - /= background_radial_mean_norm[self.background_mask] - self.background_radial_mean[np.logical_not(self.background_mask)] = 0 - - # variance and standard deviation - self.background_radial_var = np.sum( - (self.background_radial - self.background_radial_mean[None,None,:])**2 \ - * self.background_radial_mask, - axis=(0,1)) - self.background_radial_var[self.background_mask] \ - /= self.background_radial_var[self.background_mask] - self.background_radial_var[np.logical_not(self.background_mask)] = 0 - self.background_radial_std = np.sqrt(self.background_radial_var) - - - if q_pixel_units: - q_axis = np.arange(self.qq.shape[0]) - else: - q_axis = self.qq[self.background_mask] - - fig,ax = plt.subplots(figsize = figsize) - ax.fill_between( - q_axis, - self.background_radial_mean[self.background_mask] \ - - self.background_radial_std[self.background_mask], - self.background_radial_mean[self.background_mask] \ - + self.background_radial_std[self.background_mask], - color = 'r', - alpha=0.2, - ) - ax.plot( - q_axis, - self.background_radial_mean[self.background_mask], - color = 'r', - linewidth = 2, - ) - - # overlay fitting model - if plot_background_model: - sig = self.background_model( - self.qq, - self.background_coefs, - ) - ax.plot( - q_axis, - sig, - color = 'k', - linewidth = 2, - linestyle = '--' - ) - - # plot appearance - ax.set_xlim(( - q_axis[0], - q_axis[-1])) - if q_pixel_units: - ax.set_xlabel( - 'Scattering Angle (pixels)', - fontsize = 14, - ) - else: - ax.set_xlabel( - 'Scattering Angle (' + self.calibration.get_Q_pixel_units() +')', - fontsize = 14, - ) - ax.set_ylabel( - 'Background Signal', - fontsize = 14, - ) - if not label_y_axis: - ax.tick_params( - left = False, - labelleft = False) - - if returnfig: - return fig,ax - - -def make_orientation_histogram( - self, - radial_ranges: np.ndarray = None, - orientation_flip_sign: bool = False, - orientation_offset_degrees: float = 0.0, - orientation_separate_bins: bool = False, - upsample_factor: float = 4.0, - use_refined_peaks = True, - use_peak_sigma = False, - peak_sigma_samples = 6, - theta_step_deg: float = None, - sigma_x: float = 1.0, - sigma_y: float = 1.0, - sigma_theta: float = 3.0, - normalize_intensity_image: bool = False, - normalize_intensity_stack: bool = True, - progress_bar: bool = True, - ): - """ - Make an orientation histogram, in order to use flowline visualization of orientation maps. - Use peaks attached to polardatacube. - - NOTE - currently assumes two fold rotation symmetry - TODO - add support for non two fold symmetry polardatacube - - Args: - radial_ranges (np array): Size (N x 2) array for N radial bins, or (2,) for a single bin. - orientation_flip_sign (bool): Flip the direction of theta - orientation_offset_degrees (float): Offset for orientation angles - orientation_separate_bins (bool): whether to place multiple angles into multiple radial bins. - upsample_factor (float): Upsample factor - use_refined_peaks (float): Use refined peak positions - use_peak_sigma (float): Spread signal along annular direction using measured std. - theta_step_deg (float): Step size along annular direction in degrees - sigma_x (float): Smoothing in x direction before upsample - sigma_y (float): Smoothing in x direction before upsample - sigma_theta (float): Smoothing in annular direction (units of bins, periodic) - normalize_intensity_image (bool): Normalize to max peak intensity = 1, per image - normalize_intensity_stack (bool): Normalize to max peak intensity = 1, all images - progress_bar (bool): Enable progress bar - - Returns: - orient_hist (array): 4D array containing Bragg peak intensity histogram - [radial_bin x_probe y_probe theta] - """ - - # coordinates - if theta_step_deg is None: - # Get angles from polardatacube - theta = self.tt - else: - theta = np.arange(0,180,theta_step_deg) * np.pi / 180.0 - dtheta = theta[1] - theta[0] - dtheta_deg = dtheta * 180 / np.pi - num_theta_bins = np.size(theta) - - # Input bins - radial_ranges = np.array(radial_ranges) - if radial_ranges.ndim == 1: - radial_ranges = radial_ranges[None,:] - radial_ranges_2 = radial_ranges**2 - num_radii = radial_ranges.shape[0] - size_input = self._datacube.shape[0:2] - - # Output size - size_output = np.round(np.array(size_input).astype('float') * upsample_factor).astype('int') - - # output init - orient_hist = np.zeros([ - num_radii, - size_output[0], - size_output[1], - num_theta_bins]) - - if use_peak_sigma: - v_sigma = np.linspace(-2,2,2*peak_sigma_samples+1) - w_sigma = np.exp(-v_sigma**2/2) - - # Loop over all probe positions - for a0 in range(num_radii): - t = "Generating histogram " + str(a0) - - for rx, ry in tqdmnd( - *size_input, - desc=t, - unit=" probe positions", - disable=not progress_bar - ): - x = (rx + 0.5)*upsample_factor - 0.5 - y = (ry + 0.5)*upsample_factor - 0.5 - x = np.clip(x,0,size_output[0]-2) - y = np.clip(y,0,size_output[1]-2) - - xF = np.floor(x).astype('int') - yF = np.floor(y).astype('int') - dx = x - xF - dy = y - yF - - add_data = False - if use_refined_peaks: - q = self.peaks_refine[rx,ry]['qr'] - else: - q = (self.peaks[rx,ry]['qr'] + self.qmin) * self._radial_step - r2 = q**2 - sub = np.logical_and(r2 >= radial_ranges_2[a0,0], r2 < radial_ranges_2[a0,1]) - - if np.any(sub): - add_data = True - intensity = self.peaks[rx,ry]['intensity'][sub] - - # Angles of all peaks - if use_refined_peaks: - theta = self.peaks_refine[rx,ry]['qt'][sub] - else: - theta = self.peaks[rx,ry]['qt'][sub] * self._annular_step - if orientation_flip_sign: - theta *= -1 - theta += orientation_offset_degrees - - t = theta / dtheta - - # If needed, expand signal using peak sigma to write into multiple bins - if use_peak_sigma: - theta_std = self.peaks_refine[rx,ry]['sigma_annular'][sub] / dtheta - t = (t[:,None] + theta_std[:,None]*v_sigma[None,:]).ravel() - intensity = (intensity[:,None] * w_sigma[None,:]).ravel() - - if add_data: - tF = np.floor(t).astype('int') - dt = t - tF - - orient_hist[a0,xF ,yF ,:] = orient_hist[a0,xF ,yF ,:] + \ - np.bincount(np.mod(tF ,num_theta_bins), - weights=(1-dx)*(1-dy)*(1-dt)*intensity,minlength=num_theta_bins) - orient_hist[a0,xF ,yF ,:] = orient_hist[a0,xF ,yF ,:] + \ - np.bincount(np.mod(tF+1,num_theta_bins), - weights=(1-dx)*(1-dy)*( dt)*intensity,minlength=num_theta_bins) - - orient_hist[a0,xF+1,yF ,:] = orient_hist[a0,xF+1,yF ,:] + \ - np.bincount(np.mod(tF ,num_theta_bins), - weights=( dx)*(1-dy)*(1-dt)*intensity,minlength=num_theta_bins) - orient_hist[a0,xF+1,yF ,:] = orient_hist[a0,xF+1,yF ,:] + \ - np.bincount(np.mod(tF+1,num_theta_bins), - weights=( dx)*(1-dy)*( dt)*intensity,minlength=num_theta_bins) - - orient_hist[a0,xF ,yF+1,:] = orient_hist[a0,xF ,yF+1,:] + \ - np.bincount(np.mod(tF ,num_theta_bins), - weights=(1-dx)*( dy)*(1-dt)*intensity,minlength=num_theta_bins) - orient_hist[a0,xF ,yF+1,:] = orient_hist[a0,xF ,yF+1,:] + \ - np.bincount(np.mod(tF+1,num_theta_bins), - weights=(1-dx)*( dy)*( dt)*intensity,minlength=num_theta_bins) - - orient_hist[a0,xF+1,yF+1,:] = orient_hist[a0,xF+1,yF+1,:] + \ - np.bincount(np.mod(tF ,num_theta_bins), - weights=( dx)*( dy)*(1-dt)*intensity,minlength=num_theta_bins) - orient_hist[a0,xF+1,yF+1,:] = orient_hist[a0,xF+1,yF+1,:] + \ - np.bincount(np.mod(tF+1,num_theta_bins), - weights=( dx)*( dy)*( dt)*intensity,minlength=num_theta_bins) - - # smoothing / interpolation - if (sigma_x is not None) or (sigma_y is not None) or (sigma_theta is not None): - if num_radii > 1: - print('Interpolating orientation matrices ...', end='') - else: - print('Interpolating orientation matrix ...', end='') - if sigma_x is not None and sigma_x > 0: - orient_hist = gaussian_filter1d( - orient_hist,sigma_x*upsample_factor, - mode='nearest', - axis=1, - truncate=3.0) - if sigma_y is not None and sigma_y > 0: - orient_hist = gaussian_filter1d( - orient_hist,sigma_y*upsample_factor, - mode='nearest', - axis=2, - truncate=3.0) - if sigma_theta is not None and sigma_theta > 0: - orient_hist = gaussian_filter1d( - orient_hist,sigma_theta/dtheta_deg, - mode='wrap', - axis=3, - truncate=2.0) - print(' done.') - - # normalization - if normalize_intensity_stack is True: - orient_hist = orient_hist / np.max(orient_hist) - elif normalize_intensity_image is True: - for a0 in range(num_radii): - orient_hist[a0,:,:,:] = orient_hist[a0,:,:,:] / np.max(orient_hist[a0,:,:,:]) - - return orient_hist \ No newline at end of file diff --git a/py4DSTEM/visualize/show.py b/py4DSTEM/visualize/show.py index 82ce248d2..3b9d99e43 100644 --- a/py4DSTEM/visualize/show.py +++ b/py4DSTEM/visualize/show.py @@ -320,9 +320,6 @@ def show( if intensity_range is None: intensity_range = clipvals - if scalebar == True: - scalebar = {} - # plot a grid if `ar` is a list, or use multichannel functionality to make an RGBa image ar = ar[0] if (isinstance(ar,list) and len(ar) == 1) else ar if isinstance(ar,list): @@ -394,6 +391,8 @@ def show( # Output image for plotting ar = ar_rgb + if scalebar == True: + scalebar = {} # support for native data types elif not isinstance(ar,np.ndarray): @@ -568,12 +567,8 @@ def show( ax.matshow(mask_display,cmap=cmap,alpha=mask_alpha,vmin=vmin,vmax=vmax) # ...or, plot its histogram else: - # hist,bin_edges = np.histogram( - # _ar, - # bins=np.linspace(np.min(_ar),np.max(_ar),num=n_bins)) - hist,bin_edges = np.histogram( - _ar, - bins=np.linspace(vmin,vmax,num=n_bins)) + hist,bin_edges = np.histogram(_ar,bins=np.linspace(np.min(_ar), + np.max(_ar),num=n_bins)) w = bin_edges[1]-bin_edges[0] x = bin_edges[:-1]+w/2. ax.bar(x,hist,width=w) From 9c60597826a40e3e51aa2e062c92dcebab416703 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 12:01:40 -0700 Subject: [PATCH 295/362] rotated --- py4DSTEM/process/strain.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 3ce202e4b..372ae7397 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -438,7 +438,7 @@ def get_strain( flip_theta=flip_theta, ) - self.data = strainmap_rotated + self.strainmap_rotated = strainmap_rotated from py4DSTEM.visualize import show_strain @@ -450,7 +450,7 @@ def get_strain( axes_plots = kwargs.pop("axes_plots", ()) fig, ax = show_strain( - self.data, + self.strainmap_rotated, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, From 855ce3d5e27ee3a2afbcc09bf2458a08078651ed Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 13:21:24 -0700 Subject: [PATCH 296/362] fix copy method --- py4DSTEM/process/strain.py | 153 +++++----------------------------- py4DSTEM/visualize/overlay.py | 22 ++--- 2 files changed, 33 insertions(+), 142 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 372ae7397..247b60a06 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -330,7 +330,7 @@ def fit_lattice_vectors( vis_params : dict additional visualization parameters passed to `show` returncalc : bool - if True, returns braggdirections, bragg_vectors_indexed, g1g2_map + if True, returns bragg_directions, bragg_vectors_indexed, g1g2_map """ # check the calstate assert ( @@ -354,7 +354,7 @@ def fit_lattice_vectors( if plot: self.show_bragg_indexing( self.bvm, - braggdirections=braggdirections, + bragg_directions=braggdirections, points=True, **vis_params, ) @@ -364,7 +364,7 @@ def fit_lattice_vectors( bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, - self.braggdirections, + self.bragg_directions, maxPeakSpacing=max_peak_spacing, qx_shift=self.braggvectors.Qshape[0] / 2, qy_shift=self.braggvectors.Qshape[1] / 2, @@ -380,7 +380,7 @@ def fit_lattice_vectors( self.g1g2_map = g1g2_map if returncalc: - braggdirections, bragg_vectors_indexed, g1g2_map + bragg_directions, bragg_vectors_indexed, g1g2_map def get_strain( self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs @@ -521,7 +521,7 @@ def show_lattice_vectors( def show_bragg_indexing( self, ar, - braggdirections, + bragg_directions, voffset=5, hoffset=0, color="w", @@ -540,13 +540,13 @@ def show_bragg_indexing( bragg_directions (PointList) the bragg scattering directions; must have coordinates 'qx','qy','h', and 'k'. Optionally may also have 'l'. """ - assert isinstance(braggdirections, PointList) + assert isinstance(bragg_directions, PointList) for k in ("qx", "qy", "h", "k"): - assert k in braggdirections.data.dtype.fields + assert k in bragg_directions.data.dtype.fields fig, ax = show(ar, returnfig=True, **kwargs) d = { - "braggdirections": braggdirections, + "bragg_directions": bragg_directions, "voffset": voffset, "hoffset": hoffset, "color": color, @@ -566,134 +566,25 @@ def show_bragg_indexing( def copy(self, name=None): name = name if name is not None else self.name + "_copy" strainmap_copy = StrainMap(self.braggvectors) + for attr in ( + "g", + "g0", + "g1", + "g2", + "calstate", + "bragg_directions", + "bragg_vectors_indexed", + "g1g2_map", + "strainmap_g1g2", + "strainmap_rotated", + ): + if hasattr(self, attr): + setattr(strainmap_copy, attr, getattr(self, attr)) for k in self.metadata.keys(): strainmap_copy.metadata = self.metadata[k].copy() return strainmap_copy - # def index_bragg_directions(x0, y0, gx, gy, g1, g2): - # """ - # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - # reciprocal lattice directions. - - # The approach is to solve the matrix equation - # ``alpha = beta * M`` - # where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, - # beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the - # h,k indices. - - # Args: - # x0 (float): x-coord of origin - # y0 (float): y-coord of origin - # gx (1d array): x-coord of the reciprocal lattice vectors - # gy (1d array): y-coord of the reciprocal lattice vectors - # g1 (2-tuple of floats): g1x,g1y - # g2 (2-tuple of floats): g2x,g2y - - # Returns: - # (3-tuple) A 3-tuple containing: - - # * **h**: *(ndarray of ints)* first index of the bragg directions - # * **k**: *(ndarray of ints)* second index of the bragg directions - # * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the - # indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y - # coords 'h' and 'k' contain h and k. - # """ - # # Get beta, the matrix of lattice vectors - # beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - - # # Get alpha, the matrix of measured bragg angles - # alpha = np.vstack([gx-x0,gy-y0]) - - # # Calculate M, the matrix of peak positions - # M = lstsq(beta, alpha, rcond=None)[0].T - # M = np.round(M).astype(int) - - # # Get h,k - # h = M[:,0] - # k = M[:,1] - - # # Store in a PointList - # coords = [('qx',float),('qy',float),('h',int),('k',int)] - # temp_array = np.zeros([], dtype = coords) - # bragg_directions = PointList(data = temp_array) - # bragg_directions.add_data_by_field((gx,gy,h,k)) - - # return h,k, bragg_directions - - # def add_indices_to_braggvectors( - # braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None - # ): - # """ - # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - # identify the indices for each peak in the PointListArray braggpeaks. - # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - # indices with the ints (h,k) and indicating whether the peak was successfully indexed - # or not with the bool index_mask. If `mask` is specified, only the locations where - # mask is True are indexed. - - # Args: - # braggpeaks (PointListArray): the braggpeaks to index. Must contain - # the coordinates 'qx', 'qy', and 'intensity' - # lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. - # Must contain the coordinates 'qx', 'qy', 'h', and 'k' - # maxPeakSpacing (float): Maximum distance from the ideal lattice points - # to include a peak for indexing - # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - # relative to the `braggpeaks` PointListArray - # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - # locations should be indexed. This can be used to index different regions of - # the scan with different lattices - - # Returns: - # (PointListArray): The original braggpeaks pointlistarray, with new coordinates - # 'h', 'k', containing the indices of each indexable peak. - # """ - - # assert isinstance(braggpeaks, PointListArray) - # assert np.all( - # [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] - # ) - # assert isinstance(lattice, PointList) - # assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - - # if mask is None: - # mask = np.ones(braggpeaks.shape, dtype=bool) - - # assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" - # assert mask.dtype == bool, "mask must be boolean" - - # indexed_braggpeaks = braggpeaks.copy() - - # # add the coordinates if they don't exist - # if not ("h" in braggpeaks.dtype.names): - # indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) - # if not ("k" in braggpeaks.dtype.names): - # indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - - # # loop over all the scan positions - # for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): - # if mask[Rx, Ry]: - # pl = indexed_braggpeaks.get_pointlist(Rx, Ry) - # rm_peak_mask = np.zeros(pl.length, dtype=bool) - - # for i in range(pl.length): - # r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( - # pl.data["qy"][i] - lattice.data["qy"] + qy_shift - # ) ** 2 - # ind = np.argmin(r2) - # if r2[ind] <= maxPeakSpacing**2: - # pl.data["h"][i] = lattice.data["h"][ind] - # pl.data["k"][i] = lattice.data["k"][ind] - # else: - # rm_peak_mask[i] = True - # pl.remove(rm_peak_mask) - - # indexed_braggpeaks.name = braggpeaks.name + "_indexed" - # return indexed_braggpeaks - # IO methods # read diff --git a/py4DSTEM/visualize/overlay.py b/py4DSTEM/visualize/overlay.py index e0c87a427..7e7147a15 100644 --- a/py4DSTEM/visualize/overlay.py +++ b/py4DSTEM/visualize/overlay.py @@ -437,7 +437,7 @@ def add_bragg_index_labels(ax,d): Adds labels for indexed bragg directions to a plot, using the parameters in dict d. The dictionary d has required and optional parameters as follows: - braggdirections (req'd) (PointList) the Bragg directions. This PointList must have + bragg_directions (req'd) (PointList) the Bragg directions. This PointList must have the fields 'qx','qy','h', and 'k', and may optionally have 'l' voffset (number) vertical offset for the labels hoffset (number) horizontal offset for the labels @@ -450,12 +450,12 @@ def add_bragg_index_labels(ax,d): # handle inputs assert isinstance(ax,Axes) # bragg directions - assert('braggdirections' in d.keys()) - braggdirections = d['braggdirections'] - assert isinstance(braggdirections,PointList) + assert('bragg_directions' in d.keys()) + bragg_directions = d['bragg_directions'] + assert isinstance(bragg_directions,PointList) for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - include_l = True if 'l' in braggdirections.data.dtype.fields else False + assert k in bragg_directions.data.dtype.fields + include_l = True if 'l' in bragg_directions.data.dtype.fields else False # offsets hoffset = d['hoffset'] if 'hoffset' in d.keys() else 0 voffset = d['voffset'] if 'voffset' in d.keys() else 5 @@ -474,20 +474,20 @@ def add_bragg_index_labels(ax,d): # add the points if points: - ax.scatter(braggdirections.data['qy'],braggdirections.data['qx'], + ax.scatter(bragg_directions.data['qy'],bragg_directions.data['qx'], color=pointcolor,s=pointsize) # add index labels - for i in range(braggdirections.length): - x,y = braggdirections.data['qx'][i],braggdirections.data['qy'][i] + for i in range(bragg_directions.length): + x,y = bragg_directions.data['qx'][i],bragg_directions.data['qy'][i] x -= voffset y += hoffset - h,k = braggdirections.data['h'][i],braggdirections.data['k'][i] + h,k = bragg_directions.data['h'][i],bragg_directions.data['k'][i] h = str(h) if h>=0 else r'$\overline{{{}}}$'.format(np.abs(h)) k = str(k) if k>=0 else r'$\overline{{{}}}$'.format(np.abs(k)) s = h+','+k if include_l: - l = braggdirections.data['l'][i] + l = bragg_directions.data['l'][i] l = str(l) if l>=0 else r'$\overline{{{}}}$'.format(np.abs(l)) s += l ax.text(y,x,s,color=color,size=size,ha='center',va='bottom') From b54fd47d63a0a9da136a03a96ee42ddb05977f34 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 13:34:13 -0700 Subject: [PATCH 297/362] hot fix for fit origin --- py4DSTEM/process/calibration/origin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 8821b43d0..2b4138a74 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -134,14 +134,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, @@ -150,7 +150,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, @@ -158,7 +158,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, From 145f1b08296a7a4279c9194f54f1144e89131be4 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 14:43:06 -0700 Subject: [PATCH 298/362] flatfield correction --- py4DSTEM/io/filereaders/read_arina.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 2982d7f7f..323b5643f 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -11,6 +11,7 @@ def read_arina( mem="RAM", binfactor: int = 1, dtype_bin: float = None, + flatfield: np.ndarray = None, ): """ @@ -26,6 +27,8 @@ def read_arina( binfactor (int): Diffraction space binning factor for bin-on-load. dtype_bin(float): specify datatype for bin on load if need something other than uint16 + flatfield (np.ndarray): + flatfield forcorrection factors Returns: DataCube @@ -60,9 +63,20 @@ def read_arina( image_index = 0 + if flatfield is None: + correction_factors = 1 + else: + # Avoid div by 0 errors -> pixel with value 0 will be set to meadian + flatfield[flatfield == 0] = 1 + correction_factors = np.median(flatfield) / flatfield + for dset in f["entry"]["data"]: image_index = _processDataSet( - f["entry"]["data"][dset], image_index, array_3D, binfactor + f["entry"]["data"][dset], + image_index, + array_3D, + binfactor, + correction_factors, ) if f.__bool__(): @@ -82,15 +96,20 @@ def read_arina( return datacube -def _processDataSet(dset, start_index, array_3D, binfactor): +def _processDataSet(dset, start_index, array_3D, binfactor, correction_factors): image_index = start_index nimages_dset = dset.shape[0] for i in range(nimages_dset): if binfactor == 1: - array_3D[image_index] = dset[i].astype(array_3D.dtype) + array_3D[image_index] = np.multiply( + dset[i].astype(array_3D.dtype), correction_factors + ) else: - array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) + array_3D[image_index] = bin2D( + np.multiply(dset[i].astype(array_3D.dtype), correction_factors), + binfactor, + ) image_index = image_index + 1 return image_index From b5a86fa07f1315188ad5f42b2c18ed6dd4aaa8ca Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 17 Jul 2023 09:45:37 -0400 Subject: [PATCH 299/362] bugfix for resampled pixel size --- py4DSTEM/preprocess/preprocess.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index c156c228e..6d35cbf5b 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -652,12 +652,7 @@ def resample_data_diffraction( if not resampling_factor: resampling_factor = old_size[2] / output_size[0] if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) - - if not resampling_factor: - resampling_factor = old_size[2] / output_size[0] - if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() * resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom From 2879ac7fdaa89c9f4878fdad1fabb2522af1d1de Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 10:47:15 -0400 Subject: [PATCH 300/362] bugfixes --- py4DSTEM/datacube/datacube.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index f56836555..1246d96be 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -125,6 +125,9 @@ def calibrate(self): self._qxx,self._qyy = np.meshgrid( dim_qx,dim_qy ) self._rxx,self._ryy = np.meshgrid( dim_rx,dim_ry ) + self._qyy_raw,self._qxx_raw = np.meshgrid( np.arange(self.Q_Ny),np.arange(self.Q_Nx) ) + self._ryy_raw,self._rxx_raw = np.meshgrid( np.arange(self.R_Ny),np.arange(self.R_Nx) ) + # coordinate meshgrids @@ -140,6 +143,18 @@ def qxx(self): @property def qyy(self): return self._qyy + @property + def rxx_raw(self): + return self._rxx_raw + @property + def ryy_raw(self): + return self._ryy_raw + @property + def qxx_raw(self): + return self._qxx_raw + @property + def qyy_raw(self): + return self._qyy_raw # coordinate meshgrids with shifted origin def qxxs(self,rx,ry): @@ -1171,7 +1186,7 @@ def get_radial_bkgrnd( # define the 2D cartesian coordinate system origin = self.calibration.get_origin() origin = origin[0][rx,ry],origin[1][rx,ry] - qxx,qyy = self.qxx-origin[0], self.qyy-origin[1] + qxx,qyy = self.qxx_raw-origin[0], self.qyy_raw-origin[1] # get distance qr in polar-elliptical coords ellipse = self.calibration.get_ellipse() @@ -1456,7 +1471,7 @@ def get_braggmask( vects = braggvectors.raw[rx,ry] # loop for idx in range(len(vects.data)): - qr = np.hypot(self.qxx-vects.qx[idx], self.qyy-vects.qy[idx]) + qr = np.hypot(self.qxx_raw-vects.qx[idx], self.qyy_raw-vects.qy[idx]) mask = np.logical_and(mask, qr>radius) return mask From 97719d78bd5de125c9d1d395ff4e7998fdad6e79 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 11:13:24 -0400 Subject: [PATCH 301/362] Revert "bugfix for resampled pixel size" --- py4DSTEM/preprocess/preprocess.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index c72240b4c..162b9a32d 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -649,7 +649,12 @@ def resample_data_diffraction( if not resampling_factor: resampling_factor = old_size[2] / output_size[0] if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() * resampling_factor) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + + if not resampling_factor: + resampling_factor = old_size[2] / output_size[0] + if datacube.calibration.get_Q_pixel_size() is not None: + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom From adfc1bc60457084bc84c0f6402bd89981ae7fb96 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 13:34:13 -0700 Subject: [PATCH 302/362] hot fix for fit origin --- py4DSTEM/process/calibration/origin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 8821b43d0..2b4138a74 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -134,14 +134,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, @@ -150,7 +150,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, @@ -158,7 +158,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, From 9a053d4d09e540c23d39e193e691da252b8e6fdd Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Thu, 15 Jun 2023 13:19:12 -0700 Subject: [PATCH 303/362] read_arina start --- py4DSTEM/io/filereaders/__init__.py | 2 +- py4DSTEM/io/filereaders/read_arina.py | 65 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 py4DSTEM/io/filereaders/read_arina.py diff --git a/py4DSTEM/io/filereaders/__init__.py b/py4DSTEM/io/filereaders/__init__.py index d256334a8..44c083856 100644 --- a/py4DSTEM/io/filereaders/__init__.py +++ b/py4DSTEM/io/filereaders/__init__.py @@ -2,4 +2,4 @@ from py4DSTEM.io.filereaders.read_K2 import read_gatan_K2_bin from py4DSTEM.io.filereaders.empad import read_empad from py4DSTEM.io.filereaders.read_mib import load_mib - +from py4DSTEM.io.filereaders.read_arina import read_arina diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py new file mode 100644 index 000000000..86ed2ee9b --- /dev/null +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -0,0 +1,65 @@ +import h5py +import numpy as np +from py4DSTEM.classes import DataCube + +def read_arina(filename, scan_width): + + """ + Args: + filename: str or Path Path to the file + scan_width: x dimension of scan + + Returns: + DataCube + """ + f = h5py.File(filename, "r") + nimages = 0 + + # Count the number of images in all datasets + for dset in f["entry"]["data"]: + nimages = nimages + f["entry"]["data"][dset].shape[0] + height = f["entry"]["data"][dset].shape[1] + width = f["entry"]["data"][dset].shape[2] + dtype = f["entry"]["data"][dset].dtype + + assert ( + nimages % scan_width < 1e-6 + ), "scan_width must be integer multiple of x*y size" + + if dtype.type is np.uint32: + print("Dataset is uint32 but will be converted to uint16") + dtype = np.dtype(np.uint16) + + array_3D = np.empty((nimages, width, height), dtype=dtype) + + image_index = 0 + + for dset in f["entry"]["data"]: + image_index = _processDataSet( + f["entry"]["data"][dset], image_index, array_3D, scan_width + ) + + if f.__bool__(): + f.close() + + scan_height = int(nimages / scan_width) + + datacube = DataCube( + array_3D.reshape( + scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + ) + ) + + return datacube + + +def _processDataSet(dset, start_index, array_3D, scan_width): + image_index = start_index + nimages_dset = dset.shape[0] + + for i in range(nimages_dset): + array_3D[image_index] = dset[i].astype(array_3D.dtype) + + image_index = image_index + 1 + + return image_index From daf2fe7dac36868055b5e971215da2a9aec87b5f Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 11:17:42 -0700 Subject: [PATCH 304/362] bug fixes and including in importfile --- py4DSTEM/io/filereaders/read_arina.py | 40 +++++++++++++++++++++------ py4DSTEM/io/importfile.py | 15 +++++----- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 86ed2ee9b..b52dc994e 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -1,17 +1,34 @@ import h5py +import hdf5plugin import numpy as np from py4DSTEM.classes import DataCube +from py4DSTEM.preprocess.utils import bin2D -def read_arina(filename, scan_width): + +def read_arina( + filename, + scan_width, + mem="RAM", + binfactor:int=1, +): """ + File reader for arina 4D-STEM datasets Args: - filename: str or Path Path to the file + filename: str with path to master file scan_width: x dimension of scan + mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is + loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" + leaves the data in storage and creates a memory map which points to + the diffraction patterns, allowing them to be retrieved individually + from storage. + binfactor (int): Diffraction space binning factor for bin-on-load. Returns: - DataCube + DataCube """ + assert mem == "RAM", "ARNIA does not support memory mapping" + f = h5py.File(filename, "r") nimages = 0 @@ -21,7 +38,10 @@ def read_arina(filename, scan_width): height = f["entry"]["data"][dset].shape[1] width = f["entry"]["data"][dset].shape[2] dtype = f["entry"]["data"][dset].dtype - + + width = width//binfactor + height = height//binfactor + assert ( nimages % scan_width < 1e-6 ), "scan_width must be integer multiple of x*y size" @@ -36,7 +56,7 @@ def read_arina(filename, scan_width): for dset in f["entry"]["data"]: image_index = _processDataSet( - f["entry"]["data"][dset], image_index, array_3D, scan_width + f["entry"]["data"][dset], image_index, array_3D, binfactor ) if f.__bool__(): @@ -53,13 +73,15 @@ def read_arina(filename, scan_width): return datacube -def _processDataSet(dset, start_index, array_3D, scan_width): +def _processDataSet(dset, start_index, array_3D, binfactor): image_index = start_index nimages_dset = dset.shape[0] for i in range(nimages_dset): - array_3D[image_index] = dset[i].astype(array_3D.dtype) - + if binfactor == 1: + array_3D[image_index] = dset[i].astype(array_3D.dtype) + else: + array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) + image_index = image_index + 1 - return image_index diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 17b052601..9048e0f7f 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -9,12 +9,11 @@ read_empad, read_dm, read_gatan_K2_bin, - load_mib + load_mib, + read_arina ) - - def import_file( filepath: Union[str, pathlib.Path], mem: Optional[str] = "RAM", @@ -37,6 +36,7 @@ def import_file( from storage. binfactor (int): Diffraction space binning factor for bin-on-load. filetype (str): Used to override automatic filetype detection. + options include "dm", "empad", "gatan_K2_bin", "mib","arina" **kwargs: any additional kwargs are passed to the downstream reader - refer to the individual filetype reader function call signatures and docstrings for more details. @@ -72,7 +72,8 @@ def import_file( "dm", "empad", "gatan_K2_bin", - "mib" + "mib", + "arina", # "kitware_counted", ], "Error: filetype not recognized" @@ -85,10 +86,10 @@ def import_file( # elif filetype == "kitware_counted": # data = read_kitware_counted(filepath, mem, binfactor, metadata=metadata, **kwargs) elif filetype == "mib": - data = load_mib(filepath, mem=mem, binfactor=binfactor,**kwargs) + data = load_mib(filepath, mem=mem, binfactor=binfactor, **kwargs) + elif filetype == "arina": + data = read_arina(filepath, mem=mem, binfactor=binfactor, **kwargs) else: raise Exception("Bad filetype!") return data - - From 1d96f9195aeb8ca4e90a713cfe713e34878389a0 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 16 Jun 2023 12:55:43 -0700 Subject: [PATCH 305/362] hdf5plugin dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index cb9da8169..b0c7fa081 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ 'numpy >= 1.19', 'scipy >= 1.5.2', 'h5py >= 3.2.0', + 'hdf5plugin >= 4.1.3', 'ncempy >= 1.8.1', 'matplotlib >= 3.2.2', 'scikit-image >= 0.17.2', From e02d4110584027cd742174c0a2902b519134d24b Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 08:29:09 -0700 Subject: [PATCH 306/362] updates for file parser and dtype --- py4DSTEM/io/filereaders/read_arina.py | 8 ++++++- py4DSTEM/io/parsefiletype.py | 32 ++++++++++++++++++++++++--- py4DSTEM/io/read.py | 6 ++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index b52dc994e..4d0b605fd 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -10,6 +10,7 @@ def read_arina( scan_width, mem="RAM", binfactor:int=1, + dtype_bin:float=None, ): """ @@ -23,6 +24,8 @@ def read_arina( the diffraction patterns, allowing them to be retrieved individually from storage. binfactor (int): Diffraction space binning factor for bin-on-load. + dtype_bin(float): specify datatype for bin on load if need something + other than uint16 Returns: DataCube @@ -50,7 +53,10 @@ def read_arina( print("Dataset is uint32 but will be converted to uint16") dtype = np.dtype(np.uint16) - array_3D = np.empty((nimages, width, height), dtype=dtype) + if dtype_bin: + array_3D = np.empty((nimages, width, height), dtype=dtype_bin) + else: + array_3D = np.empty((nimages, width, height), dtype=dtype) image_index = 0 diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index 5903ce814..b2889511a 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -1,9 +1,13 @@ # File parser utility from os.path import splitext +import py4DSTEM.io.legacy as legacy +import emdfile as emd +import h5py def _parse_filetype(fp): - """ Accepts a path to a data file, and returns the file type as a string. + """ + Accepts a path to a data file, and returns the file type as a string. """ _, fext = splitext(fp) fext = fext.lower() @@ -13,7 +17,16 @@ def _parse_filetype(fp): ".py4dstem", ".emd", ]: - return "H5" + if emd._is_EMD_file(fp): + return "emd" + + elif legacy.is_py4DSTEM_file(fp): + return "legacy" + + elif _is_arina(fp): + return "arina" + + elif fext in [ ".dm", ".dm3", @@ -33,5 +46,18 @@ def _parse_filetype(fp): else: raise Exception(f"Unrecognized file extension {fext}.") - +def _is_arina(filepath): + """ + Check if an h5 file is an Arina file. + """ + with h5py.File(filepath,'r') as f: + try: + assert("entry" in f.keys()) + except AssertionError: + return False + try: + assert("NX_class" in f["entry"].attrs.keys()) + except AssertionError: + return False + return True diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index 79291fe86..f9290aac4 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -70,7 +70,7 @@ def read( assert(exists(filepath)), er2 filetype = _parse_filetype(filepath) - assert filetype == "H5", f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" + assert filetype in ('emd', 'legacy'), f"`py4DSTEM.read` loads native HDF5 formatted files, but a file of type {filetype} was detected. Try loading it using py4DSTEM.import_file" # support older `root` input if datapath is None: @@ -78,7 +78,7 @@ def read( datapath = kwargs['root'] # EMD 1.0 formatted files (py4DSTEM v0.14+) - if emd._is_EMD_file(filepath): + if filetype == "emd": version = emd._get_EMD_version(filepath) if verbose: print(f"EMD version {version[0]}.{version[1]}.{version[2]} detected. Reading...") assert emd._version_is_geq(version,(1,0,0)), f"EMD version {version} detected. Expected version >= 1.0.0" @@ -127,7 +127,7 @@ def read( # legacy py4DSTEM files (v <= 0.13) else: - assert legacy.is_py4DSTEM_file(filepath), "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." + assert filetype == "legacy", "path points to an H5 file which is neither an EMD 1.0+ file, nor a recognized legacy py4DSTEM file." # read v13 From f64f926382487e2ebac8f58913228157d0c3c0df Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 09:20:35 -0700 Subject: [PATCH 307/362] read abTEM --- py4DSTEM/io/filereaders/__init__.py | 1 + py4DSTEM/io/filereaders/read_abTEM.py | 59 +++++++++++++++++++++++++++ py4DSTEM/io/filereaders/read_arina.py | 20 ++++----- py4DSTEM/io/importfile.py | 8 +++- py4DSTEM/io/parsefiletype.py | 16 +++++++- 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 py4DSTEM/io/filereaders/read_abTEM.py diff --git a/py4DSTEM/io/filereaders/__init__.py b/py4DSTEM/io/filereaders/__init__.py index 44c083856..b6f4eb0a2 100644 --- a/py4DSTEM/io/filereaders/__init__.py +++ b/py4DSTEM/io/filereaders/__init__.py @@ -3,3 +3,4 @@ from py4DSTEM.io.filereaders.empad import read_empad from py4DSTEM.io.filereaders.read_mib import load_mib from py4DSTEM.io.filereaders.read_arina import read_arina +from py4DSTEM.io.filereaders.read_abTEM import read_abTEM diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py new file mode 100644 index 000000000..3e60f5fee --- /dev/null +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -0,0 +1,59 @@ +import h5py +from py4DSTEM.classes import DataCube + + +def read_abTEM( + filename, + mem="RAM", + binfactor: int = 1, +): + """ + File reader for abTEM 4D-STEM datasets + Args: + filename: str with path to master file + scan_width: x dimension of scan + mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is + loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" + leaves the data in storage and creates a memory map which points to + the diffraction patterns, allowing them to be retrieved individually + from storage. + binfactor (int): Diffraction space binning factor for bin-on-load. + + Returns: + DataCube + """ + assert mem == "RAM", "read_abTEM does not support memory mapping" + assert binfactor == 1, "abTEM files can only be read at full resolution" + + with h5py.File(filename, "r") as f: + datasets = {} + for key in f.keys(): + datasets[key] = f.get(key)[()] + + data = datasets["array"] + assert len(data.shape) == 4, "reader is for 4D-STEM datasets only" + + datacube = DataCube(data=data) + + sampling = datasets["sampling"] + units = datasets["units"] + + datacube.calibration.set_R_pixel_size(sampling[0]) + if sampling[0] != sampling[1]: + print( + "Warning: py4DSTEM currently only handles uniform x,y sampling. Setting sampling with x calibration" + ) + datacube.calibration.set_Q_pixel_size(sampling[2]) + if sampling[2] != sampling[3]: + print( + "Warning: py4DSTEM currently only handles uniform qx,qy sampling. Setting sampling with qx calibration" + ) + + if units[0] == b"\xc3\x85": + datacube.calibration.set_R_pixel_units("A") + else: + datacube.calibration.set_R_pixel_units(units[0].decode("utf-8")) + + datacube.calibration.set_Q_pixel_units(units[2].decode("utf-8")) + + return datacube diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 4d0b605fd..0f334f52b 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -9,8 +9,8 @@ def read_arina( filename, scan_width, mem="RAM", - binfactor:int=1, - dtype_bin:float=None, + binfactor: int = 1, + dtype_bin: float = None, ): """ @@ -24,13 +24,13 @@ def read_arina( the diffraction patterns, allowing them to be retrieved individually from storage. binfactor (int): Diffraction space binning factor for bin-on-load. - dtype_bin(float): specify datatype for bin on load if need something + dtype_bin(float): specify datatype for bin on load if need something other than uint16 Returns: DataCube """ - assert mem == "RAM", "ARNIA does not support memory mapping" + assert mem == "RAM", "read_arina does not support memory mapping" f = h5py.File(filename, "r") nimages = 0 @@ -41,10 +41,10 @@ def read_arina( height = f["entry"]["data"][dset].shape[1] width = f["entry"]["data"][dset].shape[2] dtype = f["entry"]["data"][dset].dtype - - width = width//binfactor - height = height//binfactor - + + width = width // binfactor + height = height // binfactor + assert ( nimages % scan_width < 1e-6 ), "scan_width must be integer multiple of x*y size" @@ -86,8 +86,8 @@ def _processDataSet(dset, start_index, array_3D, binfactor): for i in range(nimages_dset): if binfactor == 1: array_3D[image_index] = dset[i].astype(array_3D.dtype) - else: + else: array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) - + image_index = image_index + 1 return image_index diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 9048e0f7f..9c3287642 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -10,7 +10,8 @@ read_dm, read_gatan_K2_bin, load_mib, - read_arina + read_arina, + read_abTEM ) @@ -36,7 +37,7 @@ def import_file( from storage. binfactor (int): Diffraction space binning factor for bin-on-load. filetype (str): Used to override automatic filetype detection. - options include "dm", "empad", "gatan_K2_bin", "mib","arina" + options include "dm", "empad", "gatan_K2_bin", "mib", "arina", "abTEM" **kwargs: any additional kwargs are passed to the downstream reader - refer to the individual filetype reader function call signatures and docstrings for more details. @@ -74,6 +75,7 @@ def import_file( "gatan_K2_bin", "mib", "arina", + "abTEM" # "kitware_counted", ], "Error: filetype not recognized" @@ -89,6 +91,8 @@ def import_file( data = load_mib(filepath, mem=mem, binfactor=binfactor, **kwargs) elif filetype == "arina": data = read_arina(filepath, mem=mem, binfactor=binfactor, **kwargs) + elif filetype == "abTEM": + data = read_abTEM(filepath, mem=mem, binfactor=binfactor, **kwargs) else: raise Exception("Bad filetype!") diff --git a/py4DSTEM/io/parsefiletype.py b/py4DSTEM/io/parsefiletype.py index b2889511a..ab7529ec6 100644 --- a/py4DSTEM/io/parsefiletype.py +++ b/py4DSTEM/io/parsefiletype.py @@ -26,7 +26,9 @@ def _parse_filetype(fp): elif _is_arina(fp): return "arina" - + elif _is_abTEM(fp): + return "abTEM" + elif fext in [ ".dm", ".dm3", @@ -61,3 +63,15 @@ def _is_arina(filepath): return False return True +def _is_abTEM(filepath): + """ + Check if an h5 file is an abTEM file. + """ + with h5py.File(filepath,'r') as f: + try: + assert("array" in f.keys()) + except AssertionError: + return False + return True + + From 5ca07285fd6ff99b493482b302ca2d170b077e16 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Sat, 17 Jun 2023 09:45:46 -0700 Subject: [PATCH 308/362] fix warning statement and doc strings --- py4DSTEM/io/filereaders/read_abTEM.py | 3 +-- py4DSTEM/io/importfile.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_abTEM.py b/py4DSTEM/io/filereaders/read_abTEM.py index 3e60f5fee..1008bcc0e 100644 --- a/py4DSTEM/io/filereaders/read_abTEM.py +++ b/py4DSTEM/io/filereaders/read_abTEM.py @@ -10,8 +10,7 @@ def read_abTEM( """ File reader for abTEM 4D-STEM datasets Args: - filename: str with path to master file - scan_width: x dimension of scan + filename: str with path to file mem (str): Must be "RAM" or "MEMMAP". Specifies how the data is loaded; "RAM" transfer the data from storage to RAM, while "MEMMAP" leaves the data in storage and creates a memory map which points to diff --git a/py4DSTEM/io/importfile.py b/py4DSTEM/io/importfile.py index 9c3287642..98ef05238 100644 --- a/py4DSTEM/io/importfile.py +++ b/py4DSTEM/io/importfile.py @@ -67,8 +67,8 @@ def import_file( filetype = _parse_filetype(filepath) if filetype is None else filetype - if filetype == 'EMD': - raise Exception("EMD file detected - use py4DSTEM.read, not py4DSTEM.import_file!") + if filetype in ('emd', 'legacy'): + raise Exception("EMD file or py4DSTEM detected - use py4DSTEM.read, not py4DSTEM.import_file!") assert filetype in [ "dm", "empad", From 065aa3cfeb8e201fb7fc575b51203c35cced9a94 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 3 Jul 2023 10:31:39 -0700 Subject: [PATCH 309/362] avoid transpose --- py4DSTEM/io/filereaders/read_arina.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index 0f334f52b..d5dbbedb9 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -71,8 +71,11 @@ def read_arina( scan_height = int(nimages / scan_width) datacube = DataCube( - array_3D.reshape( - scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + np.flip( + array_3D.reshape( + scan_width, scan_height, array_3D.data.shape[1], array_3D.data.shape[2] + ), + 0, ) ) From 8686770d7bac35d2780ef5616bce9bcdd62aa6f3 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 10:58:38 -0400 Subject: [PATCH 310/362] more import fixes, all tests passing --- py4DSTEM/io/read.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/io/read.py b/py4DSTEM/io/read.py index f9290aac4..6c693b534 100644 --- a/py4DSTEM/io/read.py +++ b/py4DSTEM/io/read.py @@ -95,7 +95,7 @@ def read( with warnings.catch_warnings(): warnings.simplefilter('ignore') cal = data.calibration - elif isinstance(data,py4DSTEM.Root): + elif isinstance(data,emd.Root): try: cal = data.metadata['calibration'] except KeyError: From cae6fa6832e440ec38cf466b8bfa8752d72b449e Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 11 Jul 2023 11:25:37 -0400 Subject: [PATCH 311/362] adds test_arina unit test --- test/test_nonnative_io/test_arina.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/test_nonnative_io/test_arina.py diff --git a/test/test_nonnative_io/test_arina.py b/test/test_nonnative_io/test_arina.py new file mode 100644 index 000000000..bf9bf8e73 --- /dev/null +++ b/test/test_nonnative_io/test_arina.py @@ -0,0 +1,19 @@ +import py4DSTEM +import emdfile +from os.path import join + + +# Set filepaths +filepath = join(py4DSTEM._TESTPATH, "test_arina/STO-STEM_bench_20us_master.h5") + + +def test_read_arina(): + + # read + data = py4DSTEM.import_file( filepath ) + + # check imported data + assert isinstance(data, emdfile.Array) + assert isinstance(data, py4DSTEM.DataCube) + + From a44fc6b6282ebe893896944d74a1668f771c74e2 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 14:43:06 -0700 Subject: [PATCH 312/362] flatfield correction --- py4DSTEM/io/filereaders/read_arina.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/io/filereaders/read_arina.py b/py4DSTEM/io/filereaders/read_arina.py index d5dbbedb9..543d8db76 100644 --- a/py4DSTEM/io/filereaders/read_arina.py +++ b/py4DSTEM/io/filereaders/read_arina.py @@ -11,6 +11,7 @@ def read_arina( mem="RAM", binfactor: int = 1, dtype_bin: float = None, + flatfield: np.ndarray = None, ): """ @@ -26,6 +27,8 @@ def read_arina( binfactor (int): Diffraction space binning factor for bin-on-load. dtype_bin(float): specify datatype for bin on load if need something other than uint16 + flatfield (np.ndarray): + flatfield forcorrection factors Returns: DataCube @@ -60,9 +63,20 @@ def read_arina( image_index = 0 + if flatfield is None: + correction_factors = 1 + else: + # Avoid div by 0 errors -> pixel with value 0 will be set to meadian + flatfield[flatfield == 0] = 1 + correction_factors = np.median(flatfield) / flatfield + for dset in f["entry"]["data"]: image_index = _processDataSet( - f["entry"]["data"][dset], image_index, array_3D, binfactor + f["entry"]["data"][dset], + image_index, + array_3D, + binfactor, + correction_factors, ) if f.__bool__(): @@ -82,15 +96,20 @@ def read_arina( return datacube -def _processDataSet(dset, start_index, array_3D, binfactor): +def _processDataSet(dset, start_index, array_3D, binfactor, correction_factors): image_index = start_index nimages_dset = dset.shape[0] for i in range(nimages_dset): if binfactor == 1: - array_3D[image_index] = dset[i].astype(array_3D.dtype) + array_3D[image_index] = np.multiply( + dset[i].astype(array_3D.dtype), correction_factors + ) else: - array_3D[image_index] = bin2D(dset[i].astype(array_3D.dtype), binfactor) + array_3D[image_index] = bin2D( + np.multiply(dset[i].astype(array_3D.dtype), correction_factors), + binfactor, + ) image_index = image_index + 1 return image_index From 641484c51b7aea32f80d138c0a7ea1aa5be3dced Mon Sep 17 00:00:00 2001 From: Steven Zeltmann Date: Mon, 17 Jul 2023 09:45:37 -0400 Subject: [PATCH 313/362] bugfix for resampled pixel size --- py4DSTEM/preprocess/preprocess.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 162b9a32d..c72240b4c 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -649,12 +649,7 @@ def resample_data_diffraction( if not resampling_factor: resampling_factor = old_size[2] / output_size[0] if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) - - if not resampling_factor: - resampling_factor = old_size[2] / output_size[0] - if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() * resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom From 942715769e85870944e282bc59f93528baed9eb4 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 11:13:24 -0400 Subject: [PATCH 314/362] Revert "bugfix for resampled pixel size" --- py4DSTEM/preprocess/preprocess.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index c72240b4c..162b9a32d 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -649,7 +649,12 @@ def resample_data_diffraction( if not resampling_factor: resampling_factor = old_size[2] / output_size[0] if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() * resampling_factor) + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) + + if not resampling_factor: + resampling_factor = old_size[2] / output_size[0] + if datacube.calibration.get_Q_pixel_size() is not None: + datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) elif method == "bilinear": from scipy.ndimage import zoom From 9f921fe564ff3220ffcb43317c599a0cdfc44a16 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 12:05:56 -0400 Subject: [PATCH 315/362] fix --- py4DSTEM/preprocess/preprocess.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/py4DSTEM/preprocess/preprocess.py b/py4DSTEM/preprocess/preprocess.py index 162b9a32d..196b84dcf 100644 --- a/py4DSTEM/preprocess/preprocess.py +++ b/py4DSTEM/preprocess/preprocess.py @@ -645,14 +645,9 @@ def resample_data_diffraction( datacube.data = fourier_resample( datacube.data, scale=resampling_factor, output_size=output_size ) - - if not resampling_factor: - resampling_factor = old_size[2] / output_size[0] - if datacube.calibration.get_Q_pixel_size() is not None: - datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) if not resampling_factor: - resampling_factor = old_size[2] / output_size[0] + resampling_factor = output_size[0] / old_size[2] if datacube.calibration.get_Q_pixel_size() is not None: datacube.calibration.set_Q_pixel_size(datacube.calibration.get_Q_pixel_size() / resampling_factor) From b57094dfe890b5002cc5a84e08a1f0cb92ce5040 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 12:14:55 -0400 Subject: [PATCH 316/362] bugfix --- py4DSTEM/process/strain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 247b60a06..c76b429fa 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -364,7 +364,7 @@ def fit_lattice_vectors( bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, - self.bragg_directions, + self.braggdirections, maxPeakSpacing=max_peak_spacing, qx_shift=self.braggvectors.Qshape[0] / 2, qy_shift=self.braggvectors.Qshape[1] / 2, From ae802d9a67e799cd6a539621136f30b0c1e8a79c Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 09:39:54 -0700 Subject: [PATCH 317/362] another origin fix --- py4DSTEM/process/calibration/origin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index cd61b77be..0b27f5a85 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -133,14 +133,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit, _ = fit_2D( + popt_x, pcov_x, qx0_fit = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit, _ = fit_2D( + popt_y, pcov_y, qy0_fit = fit_2D( f, qy0_meas, robust=robust, @@ -149,7 +149,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit, _ = fit_2D( + popt_x, pcov_x, qx0_fit = fit_2D( f, qx0_meas, robust=robust, @@ -157,7 +157,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit, _ = fit_2D( + popt_y, pcov_y, qy0_fit = fit_2D( f, qy0_meas, robust=robust, From 478905c7b5552d2e47d0d769ea2e130ce402db38 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 12:17:21 -0700 Subject: [PATCH 318/362] this bug is so confusing --- py4DSTEM/process/calibration/origin.py | 8 ++++---- py4DSTEM/process/fit/fit.py | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 0b27f5a85..cd61b77be 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -133,14 +133,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, @@ -149,7 +149,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, @@ -157,7 +157,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, diff --git a/py4DSTEM/process/fit/fit.py b/py4DSTEM/process/fit/fit.py index e3bb4d86e..4a75d5c68 100644 --- a/py4DSTEM/process/fit/fit.py +++ b/py4DSTEM/process/fit/fit.py @@ -58,12 +58,9 @@ def fit_2D(function, data, data_mask=None, popt=None, fitting. Returns: - (3-tuple) A 3-tuple containing: - - * **popt**: optimal fit parameters to function - * **pcov**: the covariance matrix - * **fit_ar**: optional. If return_ar==True, fit_ar is returned, and is an - array of the same shape as data, containing the fit values + (popt,pcov,fit_at, mask) : 4-tuple + The optimal fit parameters, the fitting covariance matrix, the + the fit array with the returned `popt` params, and the mask """ shape = data.shape shape1D = [1,np.prod(shape)] @@ -101,7 +98,7 @@ def fit_2D(function, data, data_mask=None, popt=None, p0=popt) fit_ar = function(xy,*popt).reshape(shape) - return popt, pcov, fit_ar + return popt, pcov, fit_ar, mask # Functions for fitting From 47216928c4bebfba6842eef317c0edc717e06293 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 12:17:49 -0700 Subject: [PATCH 319/362] verbose should be False for braggvectors --- py4DSTEM/braggvectors/braggvectors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 14b89fd98..9a4400794 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -65,7 +65,7 @@ def __init__( Rshape, Qshape, name = 'braggvectors', - verbose = True, + verbose = False, calibration = None ): Custom.__init__(self,name=name) From 97ee5dcc47411614382ef8c08102023693260d15 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 12:55:59 -0700 Subject: [PATCH 320/362] flake fix --- py4DSTEM/process/strain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index c76b429fa..db252f75b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -380,7 +380,7 @@ def fit_lattice_vectors( self.g1g2_map = g1g2_map if returncalc: - bragg_directions, bragg_vectors_indexed, g1g2_map + braggdirections, bragg_vectors_indexed, g1g2_map def get_strain( self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs From 97d7e93f5775b91bcc033f1dcdc5dcf158fcd94b Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 16:04:03 -0400 Subject: [PATCH 321/362] bvects.copy bugfix --- py4DSTEM/braggvectors/braggvectors.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index e3173e466..851579ea8 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -293,17 +293,17 @@ def get_vectors( def copy(self, name=None): name = name if name is not None else self.name+"_copy" braggvector_copy = BraggVectors( - self.Rshape, - self.Qshape, - name=name, + self.Rshape, + self.Qshape, + name=name, calibration = self.calibration.copy() ) - - braggvector_copy._v_uncal = self._v_uncal.copy() + + braggvector_copy.set_raw_vectors( self._v_uncal.copy() ) for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() - # TODO - fix this calibration line? braggvector_copy.calibration = self.calibration + braggvector_copy.setcal() return braggvector_copy From e9e92634742879fa55628a3c1f89d2f4cf1dd866 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 16:26:51 -0400 Subject: [PATCH 322/362] bvects.copy bugfix --- py4DSTEM/braggvectors/braggvectors.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 851579ea8..5d03e40d1 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -302,8 +302,6 @@ def copy(self, name=None): braggvector_copy.set_raw_vectors( self._v_uncal.copy() ) for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() - braggvector_copy.calibration = self.calibration - braggvector_copy.setcal() return braggvector_copy From f9b0b6c531af598cd039361249bcd73d90fae011 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 16:26:51 -0400 Subject: [PATCH 323/362] bvects.copy bugfix --- py4DSTEM/braggvectors/braggvectors.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 851579ea8..5d03e40d1 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -302,8 +302,6 @@ def copy(self, name=None): braggvector_copy.set_raw_vectors( self._v_uncal.copy() ) for k in self.metadata.keys(): braggvector_copy.metadata = self.metadata[k].copy() - braggvector_copy.calibration = self.calibration - braggvector_copy.setcal() return braggvector_copy From 36bcf8d46ffc47be24c198bc5acbf913824a1e2c Mon Sep 17 00:00:00 2001 From: cophus Date: Mon, 17 Jul 2023 13:30:53 -0700 Subject: [PATCH 324/362] Update defaults in polar peaks, docstrings --- py4DSTEM/process/polar/polar_peaks.py | 40 ++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index 3f367b398..c88b8d231 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -34,7 +34,8 @@ def find_peaks_single_pattern( return_background = False, plot_result = True, plot_power_scale = 1.0, - plot_scale_size = 100.0, + plot_scale_size = 10.0, + figsize = (6,6), returnfig = False, ): """ @@ -62,10 +63,41 @@ def find_peaks_single_pattern( radial_background_thresh: float Relative order of sorted values to use as background estimate. Setting to 0.5 is equivalent to median, 0.0 is min value. - + num_peaks_max = 100 + Max number of peaks to return. + threshold_abs: float + Absolute image intensity threshold for peaks. + threshold_prom_annular: float + Threshold for prominance, along annular direction. + threshold_prom_radial: float + Threshold for prominance, along radial direction. + remove_masked_peaks: bool + Delete peaks that are in the region masked by "mask" + scale_sigma_annular: float + Scaling of the estimated annular standard deviation. + scale_sigma_radial: float + Scaling of the estimated radial standard deviation. + return_background: bool + Return the background signal. + plot_result: + Plot the detector peaks + plot_power_scale: float + Image intensity power law scaling. + plot_scale_size: float + Marker scaling in the plot. + figsize: 2-tuple + Size of the result plotting figure. + returnfig: bool + Return the figure and axes handles. + Returns -------- + peaks_polar : pointlist + The detected peaks + fig, ax : (optional) + Figure and axes handles + """ # if needed, generate mask from Bragg peaks @@ -151,7 +183,7 @@ def find_peaks_single_pattern( trace_annular, annular_ind_center, ) - sigma_annular = scale_sigma_annular * np.maximum( + sigma_annular = scale_sigma_annular * np.minimum( annular_ind_center - p_annular[1], p_annular[2] - annular_ind_center) @@ -161,7 +193,7 @@ def find_peaks_single_pattern( trace_radial, np.atleast_1d(peaks[a0,1]), ) - sigma_radial = scale_sigma_radial * np.maximum( + sigma_radial = scale_sigma_radial * np.minimum( peaks[a0,1] - p_radial[1], p_radial[2] - peaks[a0,1]) From 6659d5f2d778323fb8aa7592428441fce988d3c0 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 16:40:30 -0400 Subject: [PATCH 325/362] bvects autocal fix --- py4DSTEM/data/calibration.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index b5ef200d8..50ec8f6f9 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -610,6 +610,7 @@ def set_QR_flip(self,x): def get_QR_flip(self): return self._get_value('QR_flip') + @call_calibrate def set_QR_rotflip(self, rot_flip): """ Args: @@ -618,8 +619,8 @@ def set_QR_rotflip(self, rot_flip): flip (bool): True indicates a Q/R axes flip """ rot,flip = rot_flip - self.set_QR_rotation_degrees(rot) - self.set_QR_flip(flip) + self._params['QR_rotation_degrees'] = rot + self._params['QR_flip'] = flip def get_QR_rotflip(self): rot = self.get_QR_rotation_degrees() flip = self.get_QR_flip() From 12d6e114eae7775f93c20a79804231bf0f6283ea Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 16:50:16 -0400 Subject: [PATCH 326/362] polar datacube instantiation bugfix --- py4DSTEM/process/polar/polar_datacube.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 3f3db0eca..652debb23 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -127,9 +127,9 @@ def set_radial_bins( self._qmax, self._qstep ) - self.qscale = self._qscale self._radial_step = self._datacube.calibration.get_Q_pixel_size() * self._qstep self.set_polar_shape() + self.qscale = self._qscale @property def qmin(self): From af475e847fdb3647e302969e86201232e2dbe722 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 20:06:14 -0400 Subject: [PATCH 327/362] fixes --- py4DSTEM/datacube/virtualimage.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/py4DSTEM/datacube/virtualimage.py b/py4DSTEM/datacube/virtualimage.py index 6731c0fd0..ad6344c7d 100644 --- a/py4DSTEM/datacube/virtualimage.py +++ b/py4DSTEM/datacube/virtualimage.py @@ -10,7 +10,7 @@ import inspect from emdfile import tqdmnd,Metadata -from py4DSTEM.data import Calibration, RealSlice, Data +from py4DSTEM.data import Calibration, RealSlice, Data, DiffractionSlice from py4DSTEM.visualize.show import show @@ -322,7 +322,7 @@ def position_detector( data = None, centered = None, calibrated = None, - shift_center = None, + shift_center = False, scan_position = None, invert = False, color = 'r', @@ -381,18 +381,22 @@ def position_detector( # data if data is None: + image = None keys = ['dp_mean','dp_max','dp_median'] for k in keys: - image = None try: - image = data.tree(k) + image = self.tree(k) break except: pass - if image is None: - image = self[0,0] + if image is None: + image = self[0,0] elif isinstance(data, np.ndarray): assert(data.shape == self.Qshape), f"Can't position a detector over an image with a shape that is different from diffraction space. Diffraction space in this dataset has shape {self.Qshape} but the image passed has shape {data.shape}" + image = data + elif isinstance(data, DiffractionSlice): + assert(data.shape == self.Qshape), f"Can't position a detector over an image with a shape that is different from diffraction space. Diffraction space in this dataset has shape {self.Qshape} but the image passed has shape {data.shape}" + image = data.data elif isinstance(data,tuple): rx,ry = data[:2] image = self[rx,ry] @@ -401,10 +405,7 @@ def position_detector( # shift center if shift_center is None: - if isinstance(data,tuple): - shift_center = True - else: - shift_center = False + shift_center = False elif shift_center == True: assert(isinstance(data,tuple)), "If shift_center is set to True, `data` should be a 2-tuple (rx,ry). To shift the detector mask while using some other input for `data`, set `shift_center` to a 2-tuple (rx,ry)" elif isinstance(shift_center,tuple): From a87a908df23b0c1cf8b9458b189d5b3c495033d8 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 22:24:07 -0400 Subject: [PATCH 328/362] let Crystal.plot_scattering work w/out all cals --- py4DSTEM/process/diffraction/crystal_viz.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal_viz.py b/py4DSTEM/process/diffraction/crystal_viz.py index 9395682a0..c6e9e1a33 100644 --- a/py4DSTEM/process/diffraction/crystal_viz.py +++ b/py4DSTEM/process/diffraction/crystal_viz.py @@ -360,6 +360,12 @@ def plot_scattering_intensity( # If Bragg peaks are passed in, compute 1D integral if bragg_peaks is not None: + # set rotate and ellipse based on their availability + rotate = bragg_peaks.calibration.get_QR_rotation_degrees() + ellipse = bragg_peaks.calibration.get_ellipse() + rotate = False if rotate is None else True + ellipse = False if ellipse is None else True + # concatenate all peaks bigpl = np.concatenate( [ @@ -367,9 +373,9 @@ def plot_scattering_intensity( rx, ry, center = True, - ellipse = True, + ellipse = ellipse, pixel = True, - rotate = True, + rotate = rotate, ).data for rx in range(bragg_peaks.shape[0]) for ry in range(bragg_peaks.shape[1]) From 6ea124b6c1b6124fcc1cce4fa0ce60b1269bd2eb Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 22:40:35 -0400 Subject: [PATCH 329/362] let Crystal.cal_pix_size work w/out all cals --- py4DSTEM/process/diffraction/crystal.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal.py b/py4DSTEM/process/diffraction/crystal.py index 3be87eb25..1c4ac9073 100644 --- a/py4DSTEM/process/diffraction/crystal.py +++ b/py4DSTEM/process/diffraction/crystal.py @@ -898,6 +898,12 @@ def calculate_bragg_peak_histogram( k = np.arange(k_min, k_max + k_step, k_step) k_num = k.shape[0] + # set rotate and ellipse based on their availability + rotate = bragg_peaks.calibration.get_QR_rotation_degrees() + ellipse = bragg_peaks.calibration.get_ellipse() + rotate = False if rotate is None else True + ellipse = False if ellipse is None else True + # concatenate all peaks bigpl = np.concatenate( [ @@ -905,9 +911,9 @@ def calculate_bragg_peak_histogram( rx, ry, center = True, - ellipse = True, + ellipse = ellipse, pixel = True, - rotate = True, + rotate = rotate, ).data for rx in range(bragg_peaks.shape[0]) for ry in range(bragg_peaks.shape[1]) From de92f647020728f91126c1b45ff5c2a6810cb850 Mon Sep 17 00:00:00 2001 From: cophus Date: Mon, 17 Jul 2023 19:53:24 -0700 Subject: [PATCH 330/362] Slight updates to polardata --- py4DSTEM/process/polar/polar_datacube.py | 10 ++-- py4DSTEM/process/polar/polar_peaks.py | 69 ++++++++++++++++++------ 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 652debb23..9de3da249 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -19,7 +19,7 @@ def __init__( n_annular = 180, qscale = None, mask = None, - mask_thresh = 0.25, + mask_thresh = 0.1, ellipse = True, two_fold_symmetry = False, ): @@ -241,7 +241,11 @@ def qscale(self): def qscale(self,x): self._qscale = x if x is not None: - self._qscale_ar = np.arange(self.polar_shape[1])**x + self._qscale_ar = (self.qq / self.qq[-1])**x + # self._qscale_ar = np.arange(self.polar_shape[1])**x + # print(self.qq) + # self._qscale_ar = (np.arange(self._qmin, self.polar_shape[1] + self._qmin) \ + # / (self.polar_shape[1] - - self._qmin))**x # expose raw data @@ -453,7 +457,7 @@ def _transform( ) # scale the normalization array by the bin density - norm_array = ans_norm*self._polarcube._annular_bin_step[np.newaxis] + norm_array = ans_norm * self._polarcube._annular_bin_step[np.newaxis] mask_bool = norm_array < mask_thresh # apply normalization diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index c88b8d231..c04a7fab8 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -5,7 +5,7 @@ from scipy.ndimage import gaussian_filter, gaussian_filter1d from scipy.signal import peak_prominences from skimage.feature import peak_local_max -from scipy.optimize import curve_fit +from scipy.optimize import curve_fit, leastsq import warnings # from emdfile import tqdmnd, PointList, PointListArray @@ -35,7 +35,7 @@ def find_peaks_single_pattern( plot_result = True, plot_power_scale = 1.0, plot_scale_size = 10.0, - figsize = (6,6), + figsize = (12,6), returnfig = False, ): """ @@ -298,7 +298,7 @@ def find_peaks_single_pattern( st = np.sin(t) - fig,ax = plt.subplots(figsize=(12,6)) + fig,ax = plt.subplots(figsize=figsize) ax.imshow( im_plot, @@ -783,6 +783,8 @@ def model_radial_background( self.background_coefs[3*a0+3] = ring_int[a0] self.background_coefs[3*a0+4] = ring_sigma[a0] self.background_coefs[3*a0+5] = ring_position[a0] + lb = np.zeros_like(self.background_coefs) + ub = np.ones_like(self.background_coefs) * np.inf # Create background model def background_model(q, *coefs): @@ -808,7 +810,7 @@ def background_model(q, *coefs): self.background_radial_mean[self.background_mask], p0 = self.background_coefs, xtol = 1e-12, - # bounds = (lb,ub), + bounds = (lb,ub), )[0] # plotting @@ -826,6 +828,7 @@ def refine_peaks( # reset_fits_to_init_positions = False, scale_sigma_estimate = 0.5, min_num_pixels_fit = 10, + maxfev = None, progress_bar = True, ): """ @@ -848,6 +851,8 @@ def refine_peaks( Factor to reduce sigma of peaks by, to prevent fit from running away. min_num_pixels_fit: int Minimum number of pixels to perform fitting + maxfev: int + Maximum number of iterations in fit. Set to a low number for a fast fit. progress_bar: bool Enable progress bar @@ -928,6 +933,11 @@ def refine_peaks( s_radial * scale_sigma_estimate, )) + # bounds + lb = np.zeros_like(coefs_all) + ub = np.ones_like(coefs_all) * np.inf + + # Construct fitting model def fit_image(basis, *coefs): coefs = np.squeeze(np.array(coefs)) @@ -960,14 +970,25 @@ def fit_image(basis, *coefs): try: with warnings.catch_warnings(): warnings.simplefilter('ignore') - coefs_all = curve_fit( - fit_image, - basis[mask_bool.ravel(),:], - im_polar[mask_bool], - p0 = coefs_all, - xtol = 1e-12, - # bounds = (lb,ub), - )[0] + if maxfev is None: + coefs_all = curve_fit( + fit_image, + basis[mask_bool.ravel(),:], + im_polar[mask_bool], + p0 = coefs_all, + xtol = 1e-12, + bounds = (lb,ub), + )[0] + else: + coefs_all = curve_fit( + fit_image, + basis[mask_bool.ravel(),:], + im_polar[mask_bool], + p0 = coefs_all, + xtol = 1e-12, + maxfev = maxfev, + bounds = (lb,ub), + )[0] # Output refined peak parameters coefs_peaks = np.reshape( @@ -983,9 +1004,24 @@ def fit_image(basis, *coefs): ]), name = 'peaks_polar') except: - # if fitting has failed, we will output the mean background signal, - # but none of the peaks. - pass + # if fitting has failed, we will still output the last iteration + # TODO - add a flag for unconverged fits + coefs_peaks = np.reshape( + coefs_all[(3*num_rings+3):], + (5,num_peaks)).T + self.peaks_refine[rx,ry] = PointList( + coefs_peaks.ravel().view([ + ('qt', float), + ('qr', float), + ('intensity', float), + ('sigma_annular', float), + ('sigma_radial', float), + ]), + name = 'peaks_polar') + + # mean background signal, + # # but none of the peaks. + # pass # Output refined parameters for background coefs_bg = coefs_all[:(3*num_rings+3)] @@ -1186,6 +1222,9 @@ def make_orientation_histogram( v_sigma = np.linspace(-2,2,2*peak_sigma_samples+1) w_sigma = np.exp(-v_sigma**2/2) + if use_refined_peaks is False: + warnings.warn("Orientation histogram is using non-refined peak positions") + # Loop over all probe positions for a0 in range(num_radii): t = "Generating histogram " + str(a0) From b9a03b63243961af082138234d298fe0ff271e49 Mon Sep 17 00:00:00 2001 From: cophus Date: Mon, 17 Jul 2023 20:11:55 -0700 Subject: [PATCH 331/362] fix for non-refined peaks in polar peaks --- py4DSTEM/process/polar/polar_peaks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index c04a7fab8..b05434233 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -1270,7 +1270,10 @@ def make_orientation_histogram( # If needed, expand signal using peak sigma to write into multiple bins if use_peak_sigma: - theta_std = self.peaks_refine[rx,ry]['sigma_annular'][sub] / dtheta + if use_refined_peaks: + theta_std = self.peaks_refine[rx,ry]['sigma_annular'][sub] / dtheta + else: + theta_std = self.peaks[rx,ry]['sigma_annular'][sub] / dtheta t = (t[:,None] + theta_std[:,None]*v_sigma[None,:]).ravel() intensity = (intensity[:,None] * w_sigma[None,:]).ravel() From a34d97e2ad62e8d214a06467baa36fb707e41f22 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 23:18:32 -0400 Subject: [PATCH 332/362] Update polar_datacube.py --- py4DSTEM/process/polar/polar_datacube.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 9de3da249..24e6aaf40 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -242,10 +242,6 @@ def qscale(self,x): self._qscale = x if x is not None: self._qscale_ar = (self.qq / self.qq[-1])**x - # self._qscale_ar = np.arange(self.polar_shape[1])**x - # print(self.qq) - # self._qscale_ar = (np.arange(self._qmin, self.polar_shape[1] + self._qmin) \ - # / (self.polar_shape[1] - - self._qmin))**x # expose raw data From 03baa807c81ae9b9e32fa2b2f93ea42ff52aaa71 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 08:23:43 -0700 Subject: [PATCH 333/362] fix for fit --- py4DSTEM/process/fit/fit.py | 211 ++++++++++++++++++++++++++++++------ 1 file changed, 177 insertions(+), 34 deletions(-) diff --git a/py4DSTEM/process/fit/fit.py b/py4DSTEM/process/fit/fit.py index 4a75d5c68..32809ddb1 100644 --- a/py4DSTEM/process/fit/fit.py +++ b/py4DSTEM/process/fit/fit.py @@ -29,41 +29,49 @@ def fit_1D_gaussian(xdata,ydata,xmin,xmax): A,mu,sigma = scale*popt[0],popt[1],popt[2] return A,mu,sigma -def fit_2D(function, data, data_mask=None, popt=None, - robust=False, robust_steps=3, robust_thresh=2): +def fit_2D( + function, + data, + data_mask=None, + popt=None, + robust=False, + robust_steps=3, + robust_thresh=2, + ): """ - Performs a 2D fit, where the fit function takes its first input in the form of a - length 2 vector (ndarray) of (x,y) positions, followed by the remaining parameters, - and the data to fit takes the form of an (n,m) shaped array. Robust fitting can be - enabled to iteratively reject outlier data points, which have a root-mean-square - error beyond the user-specified threshold. - - Args: - function: First input should be a length 2 array xy, where (xy[0],xy[1]) are the - (x,y) coordinates - data: Data to fit, in an (n,m) shaped ndarray - data_mask: Optional parameter. If specified, must be a boolean array of the same - shape as data, specifying which elements of data to use in the fit - return_ar: Optional parameter. If False, only the fit parameters and covariance - matrix are returned. If True, return an array of the same shape as data with - the fit values. Defaults to True - popt: Optional parameter for input. If specified, should be a tuple of initial - guesses for the fit parameters. - robust: Optional parameter. If set to True, fit will be repeated with outliers - removed. - robust_steps: Optional parameter. Number of robust iterations performed after - initial fit. - robust_thresh: Optional parameter. Threshold for including points, in units of - root-mean-square (standard deviations) error of the predicted values after - fitting. + Performs a 2D fit. + + TODO: make returning the mask optional + + Parameters + ---------- + function : callable + Some `function( xy, **p)` where `xy` is a length 2 vector (1D np array) + specifying the pixel position (x,y), and `p` is the function parameters + data : ndarray + Some 2D array of any shape (n,m) + data_mask : None or boolean array of shape (n,m), optional + If specified, fits only the pixels in `data` where this array is True + popt : dict + Initial guess at the parameters `p` of `function`. Note that positions + in pixels (i.e. the xy positions) are linearly scaled to the space [0,1] + robust : bool + Toggles robust fitting, which iteratively rejects outlier data points + which have a root-mean-square error beyond `robust_thresh` + robust_steps : int + The number of robust fitting iterations to perform + robust_thresh : int + The robust fitting cutoff Returns: (popt,pcov,fit_at, mask) : 4-tuple The optimal fit parameters, the fitting covariance matrix, the the fit array with the returned `popt` params, and the mask """ + # get shape shape = data.shape shape1D = [1,np.prod(shape)] + # x and y coordinates normalized from 0 to 1 x,y = np.linspace(0, 1, shape[0]),np.linspace(0, 1, shape[1]) ry,rx = np.meshgrid(y,x) @@ -75,8 +83,10 @@ def fit_2D(function, data, data_mask=None, popt=None, if robust==False: robust_steps=0 - # least squares fitting - 1st iteration + # least squares fitting for k in range(robust_steps+1): + + # in 1st iteration, set up params and mask if k == 0: if popt is None: popt = np.zeros((1,len(signature(function).parameters)-1)) @@ -84,16 +94,21 @@ def fit_2D(function, data, data_mask=None, popt=None, mask = data_mask else: mask = np.ones(shape,dtype=bool) + + # otherwise, get fitting error and add high error pixels to mask else: - fit_mean_square_error = (function(xy,*popt).reshape(shape) - data)**2 - mask = fit_mean_square_error <= np.mean(fit_mean_square_error) * robust_thresh**2 - # include user-specified mask if provided - if data_mask is not None: - mask[data_mask==False] = False + fit_mean_square_error = ( + function(xy,*popt).reshape(shape) - data)**2 + _mask = fit_mean_square_error > np.mean( + fit_mean_square_error) * robust_thresh**2 + mask[_mask] == False # perform fitting - popt, pcov = curve_fit(function, - np.vstack((rx_1D[mask.reshape(shape1D)],ry_1D[mask.reshape(shape1D)])), + popt, pcov = curve_fit( + function, + np.vstack(( + rx_1D[mask.reshape(shape1D)], + ry_1D[mask.reshape(shape1D)])), data[mask], p0=popt) @@ -124,5 +139,133 @@ def bezier_two(xy, c00, c01, c02, c10, c11, c12, c20, c21, c22): c12*2*(1-xy[0])*xy[0] * (xy[1]**2) + \ c22 *(xy[0]**2) * (xy[1]**2) +def polar_gaussian_2D( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + C, + ): + # unpack position + t,q = tq + # set theta value to its closest periodic reflection to mu_t + #t = np.square(t-mu_t) + #t2 = np.min(np.vstack([t,1-t])) + t2 = np.square(t-mu_t) + return \ + I0 * np.exp( + - ( t2/(2*sigma_t**2) + \ + (q-mu_q)**2/(2*sigma_q**2) ) ) + C + + +def polar_twofold_gaussian_2D( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + ): + + # unpack position + t,q = tq + + # theta periodicity + dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 + + # output intensity + return I0 * np.exp( + (dt**2 / (-2.0*sigma_t**2)) + \ + ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) + +def polar_twofold_gaussian_2D_background( + tq, + I0, + mu_t, + mu_q, + sigma_t, + sigma_q, + C, + ): + + # unpack position + t,q = tq + # theta periodicity + dt = np.mod(t - mu_t + np.pi/2, np.pi) - np.pi/2 + + # output intensity + return C + I0 * np.exp( + (dt**2 / (-2.0*sigma_t**2)) + \ + ((q - mu_q)**2 / (-2.0*sigma_q**2)) ) + + +def fit_2D_polar_gaussian( + data, + mask = None, + p0 = None, + robust = False, + robust_steps = 3, + robust_thresh = 2, + constant_background = False, + ): + """ + + NOTE - this cannot work without using pixel coordinates - something is wrong in the workflow. + + + Fits a 2D gaussian to the pixels in `data` which are set to True in `mask`. + + The gaussian is anisotropic and oriented along (t,q), centered at + (mu_t,mu_q), has standard deviations (sigma_t,sigma_q), maximum of I0, + and an optional constant offset of C, and is periodic in t. + + f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + or + f(x,y) = I0 * exp( - (x-mu_x)^2/(2sig_x^2) + (y-mu_y)^2/(2sig_y^2) ) + C + + Parameters + ---------- + data : 2d array + the data to fit + p0 : 6-tuple + initial guess at fit parameters, (I0,mu_x,mu_y,sigma_x_sigma_y,C) + mask : 2d boolean array + ignore pixels where mask is False + robust : bool + toggle robust fitting + robust_steps : int + number of robust fit iterations + robust_thresh : number + the robust fitting threshold + constant_background : bool + whether or not to include constant background + + Returns + ------- + (popt,pcov,fit_ar) : 3-tuple + the optimal fit parameters, the covariance matrix, and the fit array + """ + if constant_background: + return fit_2D( + polar_twofold_gaussian_2D_background, + data = data, + data_mask = mask, + popt = p0, + robust = robust, + robust_steps = robust_steps, + robust_thresh = robust_thresh + ) + else: + return fit_2D( + polar_twofold_gaussian_2D, + data = data, + data_mask = mask, + popt = p0, + robust = robust, + robust_steps = robust_steps, + robust_thresh = robust_thresh + ) From 24e6c256ac1a9abeaebddbfd7731406673e7a488 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 21:48:25 -0400 Subject: [PATCH 334/362] updates --- py4DSTEM/process/strain.py | 402 ++++++++++++++++++++++++++---- py4DSTEM/visualize/vis_special.py | 96 ------- test/test_strain.py | 2 + 3 files changed, 351 insertions(+), 149 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index e999c02d1..3088afa51 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -1,10 +1,12 @@ # Defines the Strain class import numpy as np +import matplotlib.pyplot as plt from typing import Optional from py4DSTEM.data import RealSlice, Data from py4DSTEM.braggvectors import BraggVectors - +from py4DSTEM.preprocess.utils import get_maxima_2D +from py4DSTEM.visualize import show,add_pointlabels,add_vector class StrainMap(RealSlice,Data): @@ -45,19 +47,26 @@ def __init__( ) # set up braggvectors + # this assigns the bvs, ensures the origin is calibrated, + # and adds the strainmap to the bvs' tree self.braggvectors = braggvectors - # TODO - how to handle changes to braggvectors - # option: register with calibrations and add a .calibrate method - # which {{does something}} when origin changes - # TODO - include ellipse cal or no? - - assert(self.root is not None) # initialize as Data - Data.__init__( - self, - calibration = self.braggvectors.calibration - ) + Data.__init__(self) + + # set calstate + # this property is used only to check to make sure that + # the braggvectors being used throughout a workflow are + # the same. The state of calibration of the vectors is noted + # here, and then checked each time the vectors are used - + # if they differ, an error message and instructions for + # re-calibration are issued + self.calstate = self.braggvectors.calstate + + # get the BVM + # a new BVM using the current calstate is computed + self.bvm = self.braggvectors.histogram() + # braggvector properties @@ -73,6 +82,20 @@ def braggvectors(self,x): self._braggvectors.tree(self,force=True) + def reset_calstate(self): + """ + Resets the calibration state. This recomputes the BVM, and removes any computations + this StrainMap instance has stored, which will need to be recomputed. + """ + del( + self.g0, + self.g1, + self.g2, + ) + self.calstate = self.braggvectors.calstate + pass + + # Class methods @@ -81,8 +104,6 @@ def choose_lattice_vectors( index_g0, index_g1, index_g2, - mode = 'centered', - plot = True, subpixel = 'multicorr', upsample_factor = 16, sigma=0, @@ -92,39 +113,94 @@ def choose_lattice_vectors( minSpacing=0, edgeBoundary=1, maxNumPeaks=10, - bvm_vis_params = {}, + figsize=(12,6), + c_indices='lightblue', + c0='g', + c1='r', + c2='r', + c_vectors='r', + c_vectorlabels='w', + size_indices=20, + width_vectors=1, + size_vectorlabels=20, + vis_params = {}, returncalc = False, + returnfig=False, ): """ Choose which lattice vectors to use for strain mapping. - Args: - index_g0 (int): origin - index_g1 (int): second point of vector 1 - index_g2 (int): second point of vector 2 - mode (str): centered or raw bragg map - plot (bool): plot bragg vector maps and vectors - subpixel (str): specifies the subpixel resolution algorithm to use. - must be in ('pixel','poly','multicorr'), which correspond - to pixel resolution, subpixel resolution by fitting a - parabola, and subpixel resultion by Fourier upsampling. - upsample_factor: the upsampling factor for the 'multicorr' - algorithm - sigma: if >0, applies a gaussian filter - maxNumPeaks: the maximum number of maxima to return - minAbsoluteIntensity, minRelativeIntensity, relativeToPeak, - minSpacing, edgeBoundary, maxNumPeaks: filtering applied - after maximum detection and before subpixel refinement + Overlays the bvm with the points detected via local 2D + maxima detection, plus an index for each point. User selects + 3 points using the overlaid indices, which are identified as + the origin and the termini of the lattice vectors g1 and g2. + + Parameters + ---------- + index_g0 : int + selected index for the origin + index_g1 : int + selected index for g1 + index_g2 :int + selected index for g2 + subpixel : str in ('pixel','poly','multicorr') + See the docstring for py4DSTEM.preprocess.get_maxima_2D + upsample_factor : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + sigma : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + minAbsoluteIntensity : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + minRelativeIntensity : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + relativeToPeak : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + minSpacing : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + edgeBoundary : number + See the py4DSTEM.preprocess.get_maxima_2D docstring + maxNumPeaks : int + See the py4DSTEM.preprocess.get_maxima_2D docstring + figsize : 2-tuple + the size of the figure + c_indices : color + color of the maxima + c0 : color + color of the origin + c1 : color + color of g1 point + c2 : color + color of g2 point + c_vectors : color + color of the g1/g2 vectors + c_vectorlabels : color + color of the vector labels + size_indices : number + size of the indices + width_vectors : number + width of the vectors + size_vectorlabels : number + size of the vector labels + vis_params : dict + additional visualization parameters passed to `show` + returncalc : bool + toggles returning the answer + returnfig : bool + toggles returning the figure + + Returns + ------- + (optional) : None or (g0,g1,g2) or (fig,(ax1,ax2)) or both of the latter """ - from py4DSTEM.process.utils import get_maxima_2D - - if mode == "centered": - bvm = self.bvm_centered - else: - bvm = self.bvm_raw + # validate inputs + for i in (index_g0,index_g1,index_g2): + assert isinstance(i,(int,np.integer)), "indices must be integers!" + # check the calstate + assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + # find the maxima g = get_maxima_2D( - bvm, + self.bvm.data, subpixel = subpixel, upsample_factor = upsample_factor, sigma = sigma, @@ -136,26 +212,246 @@ def choose_lattice_vectors( maxNumPeaks = maxNumPeaks, ) - self.g = g - - from py4DSTEM.visualize import select_lattice_vectors - g1,g2 = select_lattice_vectors( - bvm, - gx = g['x'], - gy = g['y'], - i0 = index_g0, - i1 = index_g1, - i2 = index_g2, - **bvm_vis_params, - ) - + # get the lattice vectors + gx,gy = g['x'],g['y'] + g0 = gx[index_g0],gy[index_g0] + g1x = gx[index_g1] - g0[0] + g1y = gy[index_g1] - g0[1] + g2x = gx[index_g2] - g0[0] + g2y = gy[index_g2] - g0[1] + g1,g2 = (g1x,g1y),(g2x,g2y) + + # make the figure + fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) + show(self.bvm.data,figax=(fig,ax1),**vis_params) + show(self.bvm.data,figax=(fig,ax2),**vis_params) + + # Add indices to left panel + d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} + d0 = {'x':gx[index_g0],'y':gy[index_g0],'size':size_indices, + 'color':c0,'fontweight':'bold','labels':[str(index_g0)]} + d1 = {'x':gx[index_g1],'y':gy[index_g1],'size':size_indices, + 'color':c1,'fontweight':'bold','labels':[str(index_g1)]} + d2 = {'x':gx[index_g2],'y':gy[index_g2],'size':size_indices, + 'color':c2,'fontweight':'bold','labels':[str(index_g2)]} + add_pointlabels(ax1,d) + add_pointlabels(ax1,d0) + add_pointlabels(ax1,d1) + add_pointlabels(ax1,d2) + + # Add vectors to right panel + dg1 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g1[0],'vy':g1[1],'width':width_vectors, + 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} + dg2 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g2[0],'vy':g2[1],'width':width_vectors, + 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} + add_vector(ax2,dg1) + add_vector(ax2,dg2) + + # store vectors + self.g0 = g0 self.g1 = g1 self.g2 = g2 - if returncalc: - return g1, g2 + # return + if returncalc and returnfig: + return (g0,g1,g2),(fig,(ax1,ax2)) + elif returncalc: + return (g0,g1,g2) + elif returnfig: + return (fig,(ax1,ax2)) + else: + return + + + + + + + + + + + + + + + +def index_bragg_directions(x0, y0, gx, gy, g1, g2): + """ + From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + reciprocal lattice directions. + + The approach is to solve the matrix equation + ``alpha = beta * M`` + where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, + beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the + h,k indices. + + Args: + x0 (float): x-coord of origin + y0 (float): y-coord of origin + gx (1d array): x-coord of the reciprocal lattice vectors + gy (1d array): y-coord of the reciprocal lattice vectors + g1 (2-tuple of floats): g1x,g1y + g2 (2-tuple of floats): g2x,g2y + + Returns: + (3-tuple) A 3-tuple containing: + + * **h**: *(ndarray of ints)* first index of the bragg directions + * **k**: *(ndarray of ints)* second index of the bragg directions + * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the + indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y + coords 'h' and 'k' contain h and k. + """ + # Get beta, the matrix of lattice vectors + beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + + # Get alpha, the matrix of measured bragg angles + alpha = np.vstack([gx-x0,gy-y0]) + + # Calculate M, the matrix of peak positions + M = lstsq(beta, alpha, rcond=None)[0].T + M = np.round(M).astype(int) + # Get h,k + h = M[:,0] + k = M[:,1] + # Store in a PointList + coords = [('qx',float),('qy',float),('h',int),('k',int)] + temp_array = np.zeros([], dtype = coords) + bragg_directions = PointList(data = temp_array) + bragg_directions.add_data_by_field((gx,gy,h,k)) + + return h,k, bragg_directions + + + +def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, + qy_shift=0, mask=None): + """ + Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + identify the indices for each peak in the PointListArray braggpeaks. + Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + indices with the ints (h,k) and indicating whether the peak was successfully indexed + or not with the bool index_mask. If `mask` is specified, only the locations where + mask is True are indexed. + + Args: + braggpeaks (PointListArray): the braggpeaks to index. Must contain + the coordinates 'qx', 'qy', and 'intensity' + lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. + Must contain the coordinates 'qx', 'qy', 'h', and 'k' + maxPeakSpacing (float): Maximum distance from the ideal lattice points + to include a peak for indexing + qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + relative to the `braggpeaks` PointListArray + mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + locations should be indexed. This can be used to index different regions of + the scan with different lattices + + Returns: + (PointListArray): The original braggpeaks pointlistarray, with new coordinates + 'h', 'k', containing the indices of each indexable peak. + """ + + assert isinstance(braggpeaks,PointListArray) + assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) + assert isinstance(lattice, PointList) + assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + + if mask is None: + mask = np.ones(braggpeaks.shape,dtype=bool) + + assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' + assert mask.dtype == bool, 'mask must be boolean' + + indexed_braggpeaks = braggpeaks.copy() + + # add the coordinates if they don't exist + if not ('h' in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) + if not ('k' in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + + # loop over all the scan positions + for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): + if mask[Rx,Ry]: + pl = indexed_braggpeaks.get_pointlist(Rx,Ry) + rm_peak_mask = np.zeros(pl.length,dtype=bool) + + for i in range(pl.length): + r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ + (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 + ind = np.argmin(r2) + if r2[ind] <= maxPeakSpacing**2: + pl.data['h'][i] = lattice.data['h'][ind] + pl.data['k'][i] = lattice.data['k'][ind] + else: + rm_peak_mask[i] = True + pl.remove(rm_peak_mask) + + indexed_braggpeaks.name = braggpeaks.name + "_indexed" + return indexed_braggpeaks + + + + + + + + + + + + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): + """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). + """ + fig,ax = show(ar,returnfig=True,**kwargs) + + # Add vectors + dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, + 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} + dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, + 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} + add_vector(ax,dg1) + add_vector(ax,dg2) + + if returnfig: + return fig,ax + else: + plt.show() + return + + + def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, + points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): + """ + Shows an array with an overlay describing the Bragg directions + + Accepts: + ar (arrray) the image + bragg_directions (PointList) the bragg scattering directions; must have coordinates + 'qx','qy','h', and 'k'. Optionally may also have 'l'. + """ + assert isinstance(braggdirections,PointList) + for k in ('qx','qy','h','k'): + assert k in braggdirections.data.dtype.fields + + fig,ax = show(ar,returnfig=True,**kwargs) + d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, + 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} + add_bragg_index_labels(ax,d) + + if returnfig: + return fig,ax + else: + plt.show() + return diff --git a/py4DSTEM/visualize/vis_special.py b/py4DSTEM/visualize/vis_special.py index b487048e2..43cf7fff8 100644 --- a/py4DSTEM/visualize/vis_special.py +++ b/py4DSTEM/visualize/vis_special.py @@ -590,102 +590,6 @@ def select_point(ar,x,y,i,color='lightblue',color_selected='r',size=20,returnfig return -def select_lattice_vectors(ar,gx,gy,i0,i1,i2, - c_indices='lightblue',c0='g',c1='r',c2='r',c_vectors='r',c_vectorlabels='w', - size_indices=20,width_vectors=1,size_vectorlabels=20, - figsize=(12,6),returnfig=False,**kwargs): - """ - This function accepts a set of reciprocal lattice points (gx,gy) and three indices - (i0,i1,i2). Using those indices as, respectively, the origin, the endpoint of g1, and - the endpoint of g2, this function computes the basis lattice vectors g1,g2, visualizes - them, and returns them. To compute these vectors without visualizing, use - latticevectors.get_selected_lattice_vectors(). - - Returns: - if returnfig==False: g1,g2 - if returnfig==True g1,g2,fig,ax - """ - from py4DSTEM.process.latticevectors import get_selected_lattice_vectors - - # Make the figure - fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) - show(ar,figax=(fig,ax1),**kwargs) - show(ar,figax=(fig,ax2),**kwargs) - - # Add indices to left panel - d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} - d0 = {'x':gx[i0],'y':gy[i0],'size':size_indices,'color':c0,'fontweight':'bold','labels':[str(i0)]} - d1 = {'x':gx[i1],'y':gy[i1],'size':size_indices,'color':c1,'fontweight':'bold','labels':[str(i1)]} - d2 = {'x':gx[i2],'y':gy[i2],'size':size_indices,'color':c2,'fontweight':'bold','labels':[str(i2)]} - add_pointlabels(ax1,d) - add_pointlabels(ax1,d0) - add_pointlabels(ax1,d1) - add_pointlabels(ax1,d2) - - # Compute vectors - g1,g2 = get_selected_lattice_vectors(gx,gy,i0,i1,i2) - - # Add vectors to right panel - dg1 = {'x0':gx[i0],'y0':gy[i0],'vx':g1[0],'vy':g1[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - dg2 = {'x0':gx[i0],'y0':gy[i0],'vx':g2[0],'vy':g2[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - add_vector(ax2,dg1) - add_vector(ax2,dg2) - - if returnfig: - return g1,g2,fig,(ax1,ax2) - else: - plt.show() - return g1,g2 - - -def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) - - # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) - - if returnfig: - return fig,ax - else: - plt.show() - return - - -def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, - points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): - """ - Shows an array with an overlay describing the Bragg directions - - Accepts: - ar (arrray) the image - bragg_directions (PointList) the bragg scattering directions; must have coordinates - 'qx','qy','h', and 'k'. Optionally may also have 'l'. - """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) - - if returnfig: - return fig,ax - else: - plt.show() - return - - def show_max_peak_spacing(ar,spacing,braggdirections,color='g',lw=2,returnfig=False,**kwargs): """ Show a circle of radius `spacing` about each Bragg direction """ diff --git a/test/test_strain.py b/test/test_strain.py index 5bfa0efd3..bc9b8b58c 100644 --- a/test/test_strain.py +++ b/test/test_strain.py @@ -27,5 +27,7 @@ def test_strainmap_instantiation(self): ) assert(isinstance(strainmap, StrainMap)) + assert(strainmap.calibration is not None) + assert(strainmap.calibration is strainmap.braggvectors.calibration) From 5b0ad3e9eeebebfbd5be59752ff83d7a846eabdb Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Thu, 13 Jul 2023 22:49:42 -0400 Subject: [PATCH 335/362] fix --- py4DSTEM/process/strain.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 3088afa51..07dcb91bd 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -87,11 +87,13 @@ def reset_calstate(self): Resets the calibration state. This recomputes the BVM, and removes any computations this StrainMap instance has stored, which will need to be recomputed. """ - del( - self.g0, - self.g1, - self.g2, - ) + for attr in ) + 'g0', + 'g1', + 'g2', + ): + if hasattr(self,attr): + delattr(self,attr) self.calstate = self.braggvectors.calstate pass From 33a6ca3e2cece946d75b8fc928723366b23fd211 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 06:18:46 -0700 Subject: [PATCH 336/362] fit lattice vectors --- py4DSTEM/process/latticevectors/fit.py | 15 +- py4DSTEM/process/latticevectors/index.py | 65 ++++-- py4DSTEM/process/strain.py | 284 +++++++++++++++-------- 3 files changed, 244 insertions(+), 120 deletions(-) diff --git a/py4DSTEM/process/latticevectors/fit.py b/py4DSTEM/process/latticevectors/fit.py index 822ffdea5..fef72aca3 100644 --- a/py4DSTEM/process/latticevectors/fit.py +++ b/py4DSTEM/process/latticevectors/fit.py @@ -104,13 +104,22 @@ def fit_lattice_vectors_all_DPs(braggpeaks, x0=0, y0=0, minNumPeaks=5): # Make RealSlice to contain outputs slicelabels = ('x0','y0','g1x','g1y','g2x','g2y','error','mask') - g1g2_map = RealSlice(data=np.zeros((braggpeaks.shape[0],braggpeaks.shape[1],8)), - slicelabels=slicelabels, name='g1g2_map') + g1g2_map = RealSlice( + data=np.zeros( + (8, braggpeaks.shape[0],braggpeaks.shape[1]) + ), + slicelabels=slicelabels, name='g1g2_map' + ) # Fit lattice vectors for (Rx, Ry) in tqdmnd(braggpeaks.shape[0],braggpeaks.shape[1]): braggpeaks_curr = braggpeaks.get_pointlist(Rx,Ry) - qx0,qy0,g1x,g1y,g2x,g2y,error = fit_lattice_vectors(braggpeaks_curr, x0, y0, minNumPeaks) + qx0,qy0,g1x,g1y,g2x,g2y,error = fit_lattice_vectors( + braggpeaks_curr, + x0, + y0, + minNumPeaks + ) # Store data if g1x is not None: g1g2_map.get_slice('x0').data[Rx,Ry] = qx0 diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index cdf6b00fd..13d41d54c 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -80,6 +80,9 @@ def index_bragg_directions(x0, y0, gx, gy, g1, g2): temp_array = np.zeros([], dtype = coords) bragg_directions = PointList(data = temp_array) bragg_directions.add_data_by_field((gx,gy,h,k)) + mask = np.zeros(bragg_directions['qx'].shape[0]) + mask[0] = 1 + bragg_directions.remove(mask) return h,k, bragg_directions @@ -152,8 +155,14 @@ def generate_lattice(ux,uy,vx,vy,x0,y0,Q_Nx,Q_Ny,h_max=None,k_max=None): return ideal_lattice -def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - qy_shift=0, mask=None): +def add_indices_to_braggvectors( + braggpeaks, + lattice, + maxPeakSpacing, + qx_shift=0, + qy_shift=0, + mask=None + ): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, identify the indices for each peak in the PointListArray braggpeaks. @@ -181,43 +190,51 @@ def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, 'h', 'k', containing the indices of each indexable peak. """ - assert isinstance(braggpeaks,PointListArray) - assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) - assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + # assert isinstance(braggpeaks,BraggVectors) + # assert isinstance(lattice, PointList) + # assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) if mask is None: - mask = np.ones(braggpeaks.shape,dtype=bool) + mask = np.ones(braggpeaks.Rshape,dtype=bool) - assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' + assert mask.shape == braggpeaks.Rshape, 'mask must have same shape as pointlistarray' assert mask.dtype == bool, 'mask must be boolean' - indexed_braggpeaks = braggpeaks.copy() - # add the coordinates if they don't exist - if not ('h' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) - if not ('k' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + coords = [('qx',float),('qy',float),('intensity',float),('h',int),('k',int)] + + indexed_braggpeaks = PointListArray( + dtype = coords, + shape = braggpeaks.Rshape, + ) + + ellipse = braggpeaks.calstate["ellipse"] # loop over all the scan positions for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): if mask[Rx,Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx,Ry) - rm_peak_mask = np.zeros(pl.length,dtype=bool) - - for i in range(pl.length): + pl = braggpeaks.get_vectors( + scan_x=Rx, + scan_y=Ry, + center=True, + ellipse=ellipse, + pixel=False, + rotate=False + ) + + for i in range(pl.data.shape[0]): r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: - pl.data['h'][i] = lattice.data['h'][ind] - pl.data['k'][i] = lattice.data['k'][ind] - else: - rm_peak_mask[i] = True - pl.remove(rm_peak_mask) + indexed_braggpeaks[Rx,Ry].add_data_by_field(( + pl.data['qx'], + pl.data['qy'], + pl.data['intensity'], + lattice.data['h'][ind], + lattice.data['k'][ind] + )) - indexed_braggpeaks.name = braggpeaks.name + "_indexed" return indexed_braggpeaks diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 07dcb91bd..ec10fe5f9 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -6,8 +6,8 @@ from py4DSTEM.data import RealSlice, Data from py4DSTEM.braggvectors import BraggVectors from py4DSTEM.preprocess.utils import get_maxima_2D -from py4DSTEM.visualize import show,add_pointlabels,add_vector - +from py4DSTEM.visualize import show,add_pointlabels,add_vector, add_bragg_index_labels +from py4DSTEM import PointList class StrainMap(RealSlice,Data): """ @@ -62,7 +62,7 @@ def __init__( # if they differ, an error message and instructions for # re-calibration are issued self.calstate = self.braggvectors.calstate - + assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed self.bvm = self.braggvectors.histogram() @@ -87,7 +87,7 @@ def reset_calstate(self): Resets the calibration state. This recomputes the BVM, and removes any computations this StrainMap instance has stored, which will need to be recomputed. """ - for attr in ) + for attr in ( 'g0', 'g1', 'g2', @@ -250,6 +250,7 @@ def choose_lattice_vectors( add_vector(ax2,dg2) # store vectors + self.g = g self.g0 = g0 self.g1 = g1 self.g2 = g2 @@ -263,75 +264,218 @@ def choose_lattice_vectors( return (fig,(ax1,ax2)) else: return + + def fit_lattice_vectors( + self, + x0 = None, + y0 = None, + max_peak_spacing = 2, + mask = None, + plot = True, + vis_params = {}, + returncalc = False, + ): + """ + From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + reciprocal lattice directions. + + Args: + x0 : floagt + x-coord of origin + y0 : float + y-coord of origin + max_peak_spacing: float + Maximum distance from the ideal lattice points + to include a peak for indexing + mask: bool + Boolean mask, same shape as the pointlistarray, indicating which + locations should be indexed. This can be used to index different regions of + the scan with different lattices + plot:bool + plot results if tru + vis_params : dict + additional visualization parameters passed to `show` + returncalc : bool + if True, returns braggdirections, bragg_vectors_indexed, g1g2_map + """ + # check the calstate + assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + if x0 is None: + x0 = self.braggvectors.Qshape[0]/2 + if y0 is None: + y0 = self.braggvectors.Qshape[0]/2 + + #index braggvectors + from py4DSTEM.process.latticevectors import index_bragg_directions + _, _, braggdirections = index_bragg_directions( + x0, + y0, + self.g['x'], + self.g['y'], + self.g1, + self.g2 + ) + self.braggdirections = braggdirections + + if plot: + self.show_bragg_indexing( + self.bvm, + braggdirections = braggdirections, + points = True, + **vis_params, + ) + + #add indicies to braggvectors + from py4DSTEM.process.latticevectors import add_indices_to_braggvectors + + bragg_vectors_indexed = add_indices_to_braggvectors( + self.braggvectors, + self.braggdirections, + maxPeakSpacing = max_peak_spacing, + qx_shift = self.braggvectors.Qshape[0]/2, + qy_shift = self.braggvectors.Qshape[1]/2, + mask = mask + ) + self.bragg_vectors_indexed = bragg_vectors_indexed + #fit bragg vectors + from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs + g1g2_map = fit_lattice_vectors_all_DPs( + self.bragg_vectors_indexed + ) + self.g1g2_map = g1g2_map + if returncalc: + braggdirections, bragg_vectors_indexed, g1g2_map + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): + """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). + """ + fig,ax = show(ar,returnfig=True,**kwargs) + # Add vectors + dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, + 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} + dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, + 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} + add_vector(ax,dg1) + add_vector(ax,dg2) + + if returnfig: + return fig,ax + else: + plt.show() + return + + def show_bragg_indexing( + self, + ar, + braggdirections, + voffset=5, + hoffset=0, + color='w', + size=20, + points=True, + pointcolor='r', + pointsize=50, + returnfig=False, + **kwargs + ): + """ + Shows an array with an overlay describing the Bragg directions + Accepts: + ar (arrray) the image + bragg_directions (PointList) the bragg scattering directions; must have coordinates + 'qx','qy','h', and 'k'. Optionally may also have 'l'. + """ + assert isinstance(braggdirections,PointList) + for k in ('qx','qy','h','k'): + assert k in braggdirections.data.dtype.fields + fig,ax = show(ar,returnfig=True,**kwargs) + d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, + 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} + add_bragg_index_labels(ax,d) + if returnfig: + return fig,ax + else: + plt.show() + return -def index_bragg_directions(x0, y0, gx, gy, g1, g2): - """ - From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - reciprocal lattice directions. - The approach is to solve the matrix equation - ``alpha = beta * M`` - where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, - beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the - h,k indices. - Args: - x0 (float): x-coord of origin - y0 (float): y-coord of origin - gx (1d array): x-coord of the reciprocal lattice vectors - gy (1d array): y-coord of the reciprocal lattice vectors - g1 (2-tuple of floats): g1x,g1y - g2 (2-tuple of floats): g2x,g2y - Returns: - (3-tuple) A 3-tuple containing: - * **h**: *(ndarray of ints)* first index of the bragg directions - * **k**: *(ndarray of ints)* second index of the bragg directions - * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the - indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y - coords 'h' and 'k' contain h and k. - """ - # Get beta, the matrix of lattice vectors - beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - # Get alpha, the matrix of measured bragg angles - alpha = np.vstack([gx-x0,gy-y0]) - # Calculate M, the matrix of peak positions - M = lstsq(beta, alpha, rcond=None)[0].T - M = np.round(M).astype(int) - # Get h,k - h = M[:,0] - k = M[:,1] - # Store in a PointList - coords = [('qx',float),('qy',float),('h',int),('k',int)] - temp_array = np.zeros([], dtype = coords) - bragg_directions = PointList(data = temp_array) - bragg_directions.add_data_by_field((gx,gy,h,k)) - return h,k, bragg_directions +# def index_bragg_directions(x0, y0, gx, gy, g1, g2): +# """ +# From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of +# lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the +# reciprocal lattice directions. +# The approach is to solve the matrix equation +# ``alpha = beta * M`` +# where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, +# beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the +# h,k indices. +# Args: +# x0 (float): x-coord of origin +# y0 (float): y-coord of origin +# gx (1d array): x-coord of the reciprocal lattice vectors +# gy (1d array): y-coord of the reciprocal lattice vectors +# g1 (2-tuple of floats): g1x,g1y +# g2 (2-tuple of floats): g2x,g2y -def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, +# Returns: +# (3-tuple) A 3-tuple containing: + +# * **h**: *(ndarray of ints)* first index of the bragg directions +# * **k**: *(ndarray of ints)* second index of the bragg directions +# * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the +# indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y +# coords 'h' and 'k' contain h and k. +# """ +# # Get beta, the matrix of lattice vectors +# beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + +# # Get alpha, the matrix of measured bragg angles +# alpha = np.vstack([gx-x0,gy-y0]) + +# # Calculate M, the matrix of peak positions +# M = lstsq(beta, alpha, rcond=None)[0].T +# M = np.round(M).astype(int) + +# # Get h,k +# h = M[:,0] +# k = M[:,1] + +# # Store in a PointList +# coords = [('qx',float),('qy',float),('h',int),('k',int)] +# temp_array = np.zeros([], dtype = coords) +# bragg_directions = PointList(data = temp_array) +# bragg_directions.add_data_by_field((gx,gy,h,k)) + +# return h,k, bragg_directions + + + +def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, @@ -407,53 +551,7 @@ def add_indices_to_braggpeaks(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - - - - def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) - - # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) - - if returnfig: - return fig,ax - else: - plt.show() - return - - - def show_bragg_indexing(ar,braggdirections,voffset=5,hoffset=0,color='w',size=20, - points=True,pointcolor='r',pointsize=50,returnfig=False,**kwargs): - """ - Shows an array with an overlay describing the Bragg directions - - Accepts: - ar (arrray) the image - bragg_directions (PointList) the bragg scattering directions; must have coordinates - 'qx','qy','h', and 'k'. Optionally may also have 'l'. - """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) - - if returnfig: - return fig,ax - else: - plt.show() - return + From 0b21b46d87046f4c0104e523e9cd01f294c614cf Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 06:38:29 -0700 Subject: [PATCH 337/362] small changes --- py4DSTEM/braggvectors/braggvector_methods.py | 6 +++--- py4DSTEM/process/strain.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 08ddbb0be..84bd72908 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -714,7 +714,7 @@ def index_bragg_directions( - def add_indices_to_braggpeaks( + def add_indices_to_braggvectors( self, maxPeakSpacing, mask = None, @@ -738,9 +738,9 @@ def add_indices_to_braggpeaks( locations should be indexed. This can be used to index different regions of the scan with different lattices """ - from py4DSTEM.process.latticevectors import add_indices_to_braggpeaks + from py4DSTEM.process.latticevectors import add_indices_to_braggvectors - bragg_peaks_indexed = add_indices_to_braggpeaks( + bragg_peaks_indexed = add_indices_to_braggvectors( self.vectors, self.braggdirections, maxPeakSpacing = maxPeakSpacing, diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index ec10fe5f9..76dbbbfb8 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -65,7 +65,7 @@ def __init__( assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed - self.bvm = self.braggvectors.histogram() + self.bvm = self.braggvectors.histogram( mode = 'cal') From 0c7887bb93cf3f7b1afa7fee97cc2c02e2df027f Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 08:38:11 -0700 Subject: [PATCH 338/362] fix calibration for bragg vectors --- py4DSTEM/process/latticevectors/index.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index 13d41d54c..e75ee09e1 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -208,20 +208,10 @@ def add_indices_to_braggvectors( shape = braggpeaks.Rshape, ) - ellipse = braggpeaks.calstate["ellipse"] - # loop over all the scan positions for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): - if mask[Rx,Ry]: - pl = braggpeaks.get_vectors( - scan_x=Rx, - scan_y=Ry, - center=True, - ellipse=ellipse, - pixel=False, - rotate=False - ) - + if mask[Rx,Ry]: + pl = braggpeaks.cal[Rx,Ry] for i in range(pl.data.shape[0]): r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 From 9ba71e4e84838847165eb24526792c9c811e9353 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 09:17:24 -0700 Subject: [PATCH 339/362] strain!!! --- py4DSTEM/process/latticevectors/index.py | 6 ++--- py4DSTEM/process/latticevectors/strain.py | 11 +++++--- py4DSTEM/process/strain.py | 33 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/py4DSTEM/process/latticevectors/index.py b/py4DSTEM/process/latticevectors/index.py index e75ee09e1..189e7f10f 100644 --- a/py4DSTEM/process/latticevectors/index.py +++ b/py4DSTEM/process/latticevectors/index.py @@ -218,9 +218,9 @@ def add_indices_to_braggvectors( ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: indexed_braggpeaks[Rx,Ry].add_data_by_field(( - pl.data['qx'], - pl.data['qy'], - pl.data['intensity'], + pl.data['qx'][i], + pl.data['qy'][i], + pl.data['intensity'][i], lattice.data['h'][ind], lattice.data['k'][ind] )) diff --git a/py4DSTEM/process/latticevectors/strain.py b/py4DSTEM/process/latticevectors/strain.py index 50b9bddc9..518f38885 100644 --- a/py4DSTEM/process/latticevectors/strain.py +++ b/py4DSTEM/process/latticevectors/strain.py @@ -71,9 +71,11 @@ def get_strain_from_reference_g1g2(g1g2_map, g1, g2): # Get RealSlice for output storage R_Nx,R_Ny = g1g2_map.get_slice('g1x').shape - strain_map = RealSlice(data=np.zeros((R_Nx,R_Ny,5)), - slicelabels=('e_xx','e_yy','e_xy','theta','mask'), - name='strain_map') + strain_map = RealSlice( + data=np.zeros((5, R_Nx, R_Ny)), + slicelabels=('e_xx','e_yy','e_xy','theta','mask'), + name='strain_map' + ) # Get reference lattice matrix g1x,g1y = g1 @@ -130,7 +132,8 @@ def get_strain_from_reference_region(g1g2_map, mask): Note 1: the strain matrix has been symmetrized, so e_xy and e_yx are identical """ assert isinstance(g1g2_map, RealSlice) - assert np.all([name in g1g2_map.slicelabels for name in ('g1x','g1y','g2x','g2y','mask')]) + assert np.all( + [name in g1g2_map.slicelabels for name in ('g1x','g1y','g2x','g2y','mask')]) assert mask.dtype == bool g1,g2 = get_reference_g1g2(g1g2_map,mask) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 76dbbbfb8..c6a8fe88e 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -352,6 +352,39 @@ def fit_lattice_vectors( if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map + def get_strain( + self, + mask = None, + returncalc = True + ): + """ + + """ + if mask is None: + mask = np.ones(self.g1g2_map.shape, dtype = "bool") + + from py4DSTEM.process.latticevectors import get_strain_from_reference_region + + strainmap_median_g1g2 = get_strain_from_reference_region( + self.g1g2_map, + mask = mask, + ) + + self.strainmap_median_g1g2 = strainmap_median_g1g2 + from py4DSTEM.visualize import show_strain + show_strain( + strainmap_median_g1g2, + vrange_exx = [-2.0, 2.0], + vrange_theta = [-2.0, 2.0], + ticknumber = 3, + axes_plots = (), + bkgrd = False, + figsize = (14,4) + ) + if returncalc: + return strainmap_median_g1g2 + + def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). """ From 0647c73dd2ec933b9382e6b29c960382f055857b Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 09:28:21 -0700 Subject: [PATCH 340/362] cleaning up formatting --- py4DSTEM/process/strain.py | 468 ++++++++++++++++++++----------------- 1 file changed, 249 insertions(+), 219 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index c6a8fe88e..afe00dba4 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -1,15 +1,17 @@ # Defines the Strain class -import numpy as np -import matplotlib.pyplot as plt from typing import Optional -from py4DSTEM.data import RealSlice, Data + +import matplotlib.pyplot as plt +import numpy as np +from py4DSTEM import PointList from py4DSTEM.braggvectors import BraggVectors +from py4DSTEM.data import Data, RealSlice from py4DSTEM.preprocess.utils import get_maxima_2D -from py4DSTEM.visualize import show,add_pointlabels,add_vector, add_bragg_index_labels -from py4DSTEM import PointList +from py4DSTEM.visualize import add_bragg_index_labels, add_pointlabels, add_vector, show + -class StrainMap(RealSlice,Data): +class StrainMap(RealSlice, Data): """ Stores strain map. @@ -17,33 +19,26 @@ class StrainMap(RealSlice,Data): """ - def __init__( - self, - braggvectors: BraggVectors, - name: Optional[str] = 'strainmap' - ): + def __init__(self, braggvectors: BraggVectors, name: Optional[str] = "strainmap"): """ TODO """ - assert(isinstance(braggvectors,BraggVectors)), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" + assert isinstance( + braggvectors, BraggVectors + ), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" # initialize as a RealSlice RealSlice.__init__( self, - name = name, - data = np.empty(( - 6, - braggvectors.Rshape[0], - braggvectors.Rshape[1], - )), - slicelabels = [ - 'exx', - 'eyy', - 'exy', - 'theta', - 'mask', - 'error' - ] + name=name, + data=np.empty( + ( + 6, + braggvectors.Rshape[0], + braggvectors.Rshape[1], + ) + ), + slicelabels=["exx", "eyy", "exy", "theta", "mask", "error"], ) # set up braggvectors @@ -65,22 +60,24 @@ def __init__( assert self.calstate["center"], "braggvectors must be centered" # get the BVM # a new BVM using the current calstate is computed - self.bvm = self.braggvectors.histogram( mode = 'cal') - - + self.bvm = self.braggvectors.histogram(mode="cal") # braggvector properties @property def braggvectors(self): return self._braggvectors + @braggvectors.setter - def braggvectors(self,x): - assert(isinstance(x,BraggVectors)), f".braggvectors must be BraggVectors, not type {type(x)}" - assert(x.calibration.origin is not None), f"braggvectors must have a calibrated origin" + def braggvectors(self, x): + assert isinstance( + x, BraggVectors + ), f".braggvectors must be BraggVectors, not type {type(x)}" + assert ( + x.calibration.origin is not None + ), f"braggvectors must have a calibrated origin" self._braggvectors = x - self._braggvectors.tree(self,force=True) - + self._braggvectors.tree(self, force=True) def reset_calstate(self): """ @@ -88,17 +85,15 @@ def reset_calstate(self): this StrainMap instance has stored, which will need to be recomputed. """ for attr in ( - 'g0', - 'g1', - 'g2', + "g0", + "g1", + "g2", ): - if hasattr(self,attr): - delattr(self,attr) + if hasattr(self, attr): + delattr(self, attr) self.calstate = self.braggvectors.calstate pass - - # Class methods def choose_lattice_vectors( @@ -106,8 +101,8 @@ def choose_lattice_vectors( index_g0, index_g1, index_g2, - subpixel = 'multicorr', - upsample_factor = 16, + subpixel="multicorr", + upsample_factor=16, sigma=0, minAbsoluteIntensity=0, minRelativeIntensity=0, @@ -115,20 +110,20 @@ def choose_lattice_vectors( minSpacing=0, edgeBoundary=1, maxNumPeaks=10, - figsize=(12,6), - c_indices='lightblue', - c0='g', - c1='r', - c2='r', - c_vectors='r', - c_vectorlabels='w', + figsize=(12, 6), + c_indices="lightblue", + c0="g", + c1="r", + c2="r", + c_vectors="r", + c_vectorlabels="w", size_indices=20, width_vectors=1, size_vectorlabels=20, - vis_params = {}, - returncalc = False, + vis_params={}, + returncalc=False, returnfig=False, - ): + ): """ Choose which lattice vectors to use for strain mapping. @@ -195,59 +190,97 @@ def choose_lattice_vectors( (optional) : None or (g0,g1,g2) or (fig,(ax1,ax2)) or both of the latter """ # validate inputs - for i in (index_g0,index_g1,index_g2): - assert isinstance(i,(int,np.integer)), "indices must be integers!" + for i in (index_g0, index_g1, index_g2): + assert isinstance(i, (int, np.integer)), "indices must be integers!" # check the calstate - assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." # find the maxima g = get_maxima_2D( self.bvm.data, - subpixel = subpixel, - upsample_factor = upsample_factor, - sigma = sigma, - minAbsoluteIntensity = minAbsoluteIntensity, - minRelativeIntensity = minRelativeIntensity, - relativeToPeak = relativeToPeak, - minSpacing = minSpacing, - edgeBoundary = edgeBoundary, - maxNumPeaks = maxNumPeaks, + subpixel=subpixel, + upsample_factor=upsample_factor, + sigma=sigma, + minAbsoluteIntensity=minAbsoluteIntensity, + minRelativeIntensity=minRelativeIntensity, + relativeToPeak=relativeToPeak, + minSpacing=minSpacing, + edgeBoundary=edgeBoundary, + maxNumPeaks=maxNumPeaks, ) # get the lattice vectors - gx,gy = g['x'],g['y'] - g0 = gx[index_g0],gy[index_g0] + gx, gy = g["x"], g["y"] + g0 = gx[index_g0], gy[index_g0] g1x = gx[index_g1] - g0[0] g1y = gy[index_g1] - g0[1] g2x = gx[index_g2] - g0[0] g2y = gy[index_g2] - g0[1] - g1,g2 = (g1x,g1y),(g2x,g2y) + g1, g2 = (g1x, g1y), (g2x, g2y) # make the figure - fig,(ax1,ax2) = plt.subplots(1,2,figsize=figsize) - show(self.bvm.data,figax=(fig,ax1),**vis_params) - show(self.bvm.data,figax=(fig,ax2),**vis_params) + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize) + show(self.bvm.data, figax=(fig, ax1), **vis_params) + show(self.bvm.data, figax=(fig, ax2), **vis_params) # Add indices to left panel - d = {'x':gx,'y':gy,'size':size_indices,'color':c_indices} - d0 = {'x':gx[index_g0],'y':gy[index_g0],'size':size_indices, - 'color':c0,'fontweight':'bold','labels':[str(index_g0)]} - d1 = {'x':gx[index_g1],'y':gy[index_g1],'size':size_indices, - 'color':c1,'fontweight':'bold','labels':[str(index_g1)]} - d2 = {'x':gx[index_g2],'y':gy[index_g2],'size':size_indices, - 'color':c2,'fontweight':'bold','labels':[str(index_g2)]} - add_pointlabels(ax1,d) - add_pointlabels(ax1,d0) - add_pointlabels(ax1,d1) - add_pointlabels(ax1,d2) + d = {"x": gx, "y": gy, "size": size_indices, "color": c_indices} + d0 = { + "x": gx[index_g0], + "y": gy[index_g0], + "size": size_indices, + "color": c0, + "fontweight": "bold", + "labels": [str(index_g0)], + } + d1 = { + "x": gx[index_g1], + "y": gy[index_g1], + "size": size_indices, + "color": c1, + "fontweight": "bold", + "labels": [str(index_g1)], + } + d2 = { + "x": gx[index_g2], + "y": gy[index_g2], + "size": size_indices, + "color": c2, + "fontweight": "bold", + "labels": [str(index_g2)], + } + add_pointlabels(ax1, d) + add_pointlabels(ax1, d0) + add_pointlabels(ax1, d1) + add_pointlabels(ax1, d2) # Add vectors to right panel - dg1 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g1[0],'vy':g1[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_1$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - dg2 = {'x0':gx[index_g0],'y0':gy[index_g0],'vx':g2[0],'vy':g2[1],'width':width_vectors, - 'color':c_vectors,'label':r'$g_2$','labelsize':size_vectorlabels,'labelcolor':c_vectorlabels} - add_vector(ax2,dg1) - add_vector(ax2,dg2) + dg1 = { + "x0": gx[index_g0], + "y0": gy[index_g0], + "vx": g1[0], + "vy": g1[1], + "width": width_vectors, + "color": c_vectors, + "label": r"$g_1$", + "labelsize": size_vectorlabels, + "labelcolor": c_vectorlabels, + } + dg2 = { + "x0": gx[index_g0], + "y0": gy[index_g0], + "vx": g2[0], + "vy": g2[1], + "width": width_vectors, + "color": c_vectors, + "label": r"$g_2$", + "labelsize": size_vectorlabels, + "labelcolor": c_vectorlabels, + } + add_vector(ax2, dg1) + add_vector(ax2, dg2) # store vectors self.g = g @@ -257,24 +290,24 @@ def choose_lattice_vectors( # return if returncalc and returnfig: - return (g0,g1,g2),(fig,(ax1,ax2)) + return (g0, g1, g2), (fig, (ax1, ax2)) elif returncalc: - return (g0,g1,g2) + return (g0, g1, g2) elif returnfig: - return (fig,(ax1,ax2)) + return (fig, (ax1, ax2)) else: return - + def fit_lattice_vectors( self, - x0 = None, - y0 = None, - max_peak_spacing = 2, - mask = None, - plot = True, - vis_params = {}, - returncalc = False, - ): + x0=None, + y0=None, + max_peak_spacing=2, + mask=None, + plot=True, + vis_params={}, + returncalc=False, + ): """ From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the @@ -300,22 +333,20 @@ def fit_lattice_vectors( if True, returns braggdirections, bragg_vectors_indexed, g1g2_map """ # check the calstate - assert(self.calstate == self.braggvectors.calstate), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." if x0 is None: - x0 = self.braggvectors.Qshape[0]/2 + x0 = self.braggvectors.Qshape[0] / 2 if y0 is None: - y0 = self.braggvectors.Qshape[0]/2 + y0 = self.braggvectors.Qshape[0] / 2 - #index braggvectors + # index braggvectors from py4DSTEM.process.latticevectors import index_bragg_directions + _, _, braggdirections = index_bragg_directions( - x0, - y0, - self.g['x'], - self.g['y'], - self.g1, - self.g2 + x0, y0, self.g["x"], self.g["y"], self.g1, self.g2 ) self.braggdirections = braggdirections @@ -323,104 +354,122 @@ def fit_lattice_vectors( if plot: self.show_bragg_indexing( self.bvm, - braggdirections = braggdirections, - points = True, + braggdirections=braggdirections, + points=True, **vis_params, ) - #add indicies to braggvectors + # add indicies to braggvectors from py4DSTEM.process.latticevectors import add_indices_to_braggvectors bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, self.braggdirections, - maxPeakSpacing = max_peak_spacing, - qx_shift = self.braggvectors.Qshape[0]/2, - qy_shift = self.braggvectors.Qshape[1]/2, - mask = mask + maxPeakSpacing=max_peak_spacing, + qx_shift=self.braggvectors.Qshape[0] / 2, + qy_shift=self.braggvectors.Qshape[1] / 2, + mask=mask, ) self.bragg_vectors_indexed = bragg_vectors_indexed - #fit bragg vectors + # fit bragg vectors from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs - g1g2_map = fit_lattice_vectors_all_DPs( - self.bragg_vectors_indexed - ) + + g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_vectors_indexed) self.g1g2_map = g1g2_map if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map - - def get_strain( - self, - mask = None, - returncalc = True - ): - """ - """ - if mask is None: - mask = np.ones(self.g1g2_map.shape, dtype = "bool") + def get_strain(self, mask=None, returncalc=True): + """ """ + if mask is None: + mask = np.ones(self.g1g2_map.shape, dtype="bool") from py4DSTEM.process.latticevectors import get_strain_from_reference_region strainmap_median_g1g2 = get_strain_from_reference_region( self.g1g2_map, - mask = mask, + mask=mask, ) self.strainmap_median_g1g2 = strainmap_median_g1g2 from py4DSTEM.visualize import show_strain + show_strain( strainmap_median_g1g2, - vrange_exx = [-2.0, 2.0], - vrange_theta = [-2.0, 2.0], - ticknumber = 3, - axes_plots = (), - bkgrd = False, - figsize = (14,4) + vrange_exx=[-2.0, 2.0], + vrange_theta=[-2.0, 2.0], + ticknumber=3, + axes_plots=(), + bkgrd=False, + figsize=(14, 4), ) if returncalc: return strainmap_median_g1g2 - - def show_lattice_vectors(ar,x0,y0,g1,g2,color='r',width=1,labelsize=20,labelcolor='w',returnfig=False,**kwargs): - """ Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy). - """ - fig,ax = show(ar,returnfig=True,**kwargs) + def show_lattice_vectors( + ar, + x0, + y0, + g1, + g2, + color="r", + width=1, + labelsize=20, + labelcolor="w", + returnfig=False, + **kwargs, + ): + """Adds the vectors g1,g2 to an image, with tail positions at (x0,y0). g1 and g2 are 2-tuples (gx,gy).""" + fig, ax = show(ar, returnfig=True, **kwargs) # Add vectors - dg1 = {'x0':x0,'y0':y0,'vx':g1[0],'vy':g1[1],'width':width, - 'color':color,'label':r'$g_1$','labelsize':labelsize,'labelcolor':labelcolor} - dg2 = {'x0':x0,'y0':y0,'vx':g2[0],'vy':g2[1],'width':width, - 'color':color,'label':r'$g_2$','labelsize':labelsize,'labelcolor':labelcolor} - add_vector(ax,dg1) - add_vector(ax,dg2) + dg1 = { + "x0": x0, + "y0": y0, + "vx": g1[0], + "vy": g1[1], + "width": width, + "color": color, + "label": r"$g_1$", + "labelsize": labelsize, + "labelcolor": labelcolor, + } + dg2 = { + "x0": x0, + "y0": y0, + "vx": g2[0], + "vy": g2[1], + "width": width, + "color": color, + "label": r"$g_2$", + "labelsize": labelsize, + "labelcolor": labelcolor, + } + add_vector(ax, dg1) + add_vector(ax, dg2) if returnfig: - return fig,ax + return fig, ax else: plt.show() return - - - - def show_bragg_indexing( - self, + self, ar, braggdirections, voffset=5, hoffset=0, - color='w', + color="w", size=20, points=True, - pointcolor='r', + pointcolor="r", pointsize=50, returnfig=False, - **kwargs + **kwargs, ): """ Shows an array with an overlay describing the Bragg directions @@ -430,31 +479,30 @@ def show_bragg_indexing( bragg_directions (PointList) the bragg scattering directions; must have coordinates 'qx','qy','h', and 'k'. Optionally may also have 'l'. """ - assert isinstance(braggdirections,PointList) - for k in ('qx','qy','h','k'): + assert isinstance(braggdirections, PointList) + for k in ("qx", "qy", "h", "k"): assert k in braggdirections.data.dtype.fields - fig,ax = show(ar,returnfig=True,**kwargs) - d = {'braggdirections':braggdirections,'voffset':voffset,'hoffset':hoffset,'color':color, - 'size':size,'points':points,'pointsize':pointsize,'pointcolor':pointcolor} - add_bragg_index_labels(ax,d) + fig, ax = show(ar, returnfig=True, **kwargs) + d = { + "braggdirections": braggdirections, + "voffset": voffset, + "hoffset": hoffset, + "color": color, + "size": size, + "points": points, + "pointsize": pointsize, + "pointcolor": pointcolor, + } + add_bragg_index_labels(ax, d) if returnfig: - return fig,ax + return fig, ax else: plt.show() return - - - - - - - - - # def index_bragg_directions(x0, y0, gx, gy, g1, g2): # """ # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of @@ -507,9 +555,9 @@ def show_bragg_indexing( # return h,k, bragg_directions - -def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, - qy_shift=0, mask=None): +def add_indices_to_braggvectors( + braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None +): """ Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, identify the indices for each peak in the PointListArray braggpeaks. @@ -537,38 +585,41 @@ def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, 'h', 'k', containing the indices of each indexable peak. """ - assert isinstance(braggpeaks,PointListArray) - assert np.all([name in braggpeaks.dtype.names for name in ('qx','qy','intensity')]) + assert isinstance(braggpeaks, PointListArray) + assert np.all( + [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] + ) assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ('qx','qy','h','k')]) + assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) if mask is None: - mask = np.ones(braggpeaks.shape,dtype=bool) + mask = np.ones(braggpeaks.shape, dtype=bool) - assert mask.shape == braggpeaks.shape, 'mask must have same shape as pointlistarray' - assert mask.dtype == bool, 'mask must be boolean' + assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" + assert mask.dtype == bool, "mask must be boolean" indexed_braggpeaks = braggpeaks.copy() # add the coordinates if they don't exist - if not ('h' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('h',int)]) - if not ('k' in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([('k',int)]) + if not ("h" in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) + if not ("k" in braggpeaks.dtype.names): + indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) # loop over all the scan positions - for Rx, Ry in tqdmnd(mask.shape[0],mask.shape[1]): - if mask[Rx,Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx,Ry) - rm_peak_mask = np.zeros(pl.length,dtype=bool) + for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): + if mask[Rx, Ry]: + pl = indexed_braggpeaks.get_pointlist(Rx, Ry) + rm_peak_mask = np.zeros(pl.length, dtype=bool) for i in range(pl.length): - r2 = (pl.data['qx'][i]-lattice.data['qx'] + qx_shift)**2 + \ - (pl.data['qy'][i]-lattice.data['qy'] + qy_shift)**2 + r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( + pl.data["qy"][i] - lattice.data["qy"] + qy_shift + ) ** 2 ind = np.argmin(r2) if r2[ind] <= maxPeakSpacing**2: - pl.data['h'][i] = lattice.data['h'][ind] - pl.data['k'][i] = lattice.data['k'][ind] + pl.data["h"][i] = lattice.data["h"][ind] + pl.data["k"][i] = lattice.data["k"][ind] else: rm_peak_mask[i] = True pl.remove(rm_peak_mask) @@ -576,40 +627,19 @@ def add_indices_to_braggvectors(braggpeaks, lattice, maxPeakSpacing, qx_shift=0, indexed_braggpeaks.name = braggpeaks.name + "_indexed" return indexed_braggpeaks - - - - - - - - - - - - - - - - - - # IO methods # TODO - copy method # read @classmethod - def _get_constructor_args(cls,group): + def _get_constructor_args(cls, group): """ Returns a dictionary of args/values to pass to the class constructor """ ar_constr_args = RealSlice._get_constructor_args(group) args = { - 'data' : ar_constr_args['data'], - 'name' : ar_constr_args['name'], + "data": ar_constr_args["data"], + "name": ar_constr_args["name"], } return args - - - From b5aff3029f7376621c51c25092185831340b77ee Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 10:11:38 -0700 Subject: [PATCH 341/362] working on strain plotting --- py4DSTEM/process/strain.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index afe00dba4..a275f9e6b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -382,7 +382,12 @@ def fit_lattice_vectors( if returncalc: braggdirections, bragg_vectors_indexed, g1g2_map - def get_strain(self, mask=None, returncalc=True): + def get_strain( + self, + mask=None, + returncalc=False, + **kwargs + ): """ """ if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") @@ -395,17 +400,30 @@ def get_strain(self, mask=None, returncalc=True): ) self.strainmap_median_g1g2 = strainmap_median_g1g2 + from py4DSTEM.visualize import show_strain - - show_strain( + figsize = kwargs.pop("figsize", (14, 4)) + vrange_exx = kwargs.pop("vrange_exx", [-2.0, 2.0]) + vrange_theta = kwargs.pop("vrange_theta", [-2.0, 2.0]) + ticknumber = kwargs.pop("ticknumber", 3) + bkgrd = kwargs.pop("bkgrd", False) + axes_plots = kwargs.pop("axes_plots",()) + + fig, ax = show_strain( strainmap_median_g1g2, - vrange_exx=[-2.0, 2.0], - vrange_theta=[-2.0, 2.0], - ticknumber=3, - axes_plots=(), - bkgrd=False, - figsize=(14, 4), + vrange_exx=vrange_exx, + vrange_theta=vrange_theta, + ticknumber=ticknumber, + axes_plots=axes_plots, + bkgrd=bkgrd, + figsize=figsize, + **kwargs, + returnfig = True, ) + + if not np.all(mask == True): + for axs in ax.flatten(): + axs.imshow(mask, alpha = 0.2, cmap = "binary") if returncalc: return strainmap_median_g1g2 From fa7168b7a9021c473232ca27185547762d21dd93 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 11:39:16 -0700 Subject: [PATCH 342/362] strain mapping functions --- py4DSTEM/braggvectors/braggvector_methods.py | 350 +++++++++---------- py4DSTEM/process/latticevectors/strain.py | 20 +- py4DSTEM/process/strain.py | 205 ++++++----- 3 files changed, 309 insertions(+), 266 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 84bd72908..597c7b166 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -664,187 +664,187 @@ def fit_p_ellipse( # Deprecated?? - def index_bragg_directions( - self, - x0 = None, - y0 = None, - plot = True, - bvm_vis_params = {}, - returncalc = False, - ): - """ - From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - reciprocal lattice directions. - - Args: - x0 (float): x-coord of origin - y0 (float): y-coord of origin - Plot (bool): plot results - """ - - if x0 is None: - x0 = self.Qshape[0]/2 - if y0 is None: - y0 = self.Qshape[0]/2 - - from py4DSTEM.process.latticevectors import index_bragg_directions - _, _, braggdirections = index_bragg_directions( - x0, - y0, - self.g['x'], - self.g['y'], - self.g1, - self.g2 - ) - - self.braggdirections = braggdirections - - if plot: - from py4DSTEM.visualize import show_bragg_indexing - show_bragg_indexing( - self.bvm_centered, - **bvm_vis_params, - braggdirections = braggdirections, - points = True - ) - - if returncalc: - return braggdirections - - - - def add_indices_to_braggvectors( - self, - maxPeakSpacing, - mask = None, - returncalc = False, - ): - """ - Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - identify the indices for each peak in the PointListArray braggpeaks. - Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - indices with the ints (h,k) and indicating whether the peak was successfully indexed - or not with the bool index_mask. If `mask` is specified, only the locations where - mask is True are indexed. - - Args: - maxPeakSpacing (float): Maximum distance from the ideal lattice points - to include a peak for indexing - qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - relative to the `braggpeaks` PointListArray - mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - locations should be indexed. This can be used to index different regions of - the scan with different lattices - """ - from py4DSTEM.process.latticevectors import add_indices_to_braggvectors - - bragg_peaks_indexed = add_indices_to_braggvectors( - self.vectors, - self.braggdirections, - maxPeakSpacing = maxPeakSpacing, - qx_shift = self.Qshape[0]/2, - qy_shift = self.Qshape[1]/2, - ) - - self.bragg_peaks_indexed = bragg_peaks_indexed - - if returncalc: - return bragg_peaks_indexed - - - def fit_lattice_vectors_all_DPs(self, returncalc = False): - """ - Fits lattice vectors g1,g2 to each diffraction pattern in braggpeaks, given some - known (h,k) indexing. - + # def index_bragg_directions( + # self, + # x0 = None, + # y0 = None, + # plot = True, + # bvm_vis_params = {}, + # returncalc = False, + # ): + # """ + # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + # reciprocal lattice directions. + + # Args: + # x0 (float): x-coord of origin + # y0 (float): y-coord of origin + # Plot (bool): plot results + # """ + + # if x0 is None: + # x0 = self.Qshape[0]/2 + # if y0 is None: + # y0 = self.Qshape[0]/2 + + # from py4DSTEM.process.latticevectors import index_bragg_directions + # _, _, braggdirections = index_bragg_directions( + # x0, + # y0, + # self.g['x'], + # self.g['y'], + # self.g1, + # self.g2 + # ) + + # self.braggdirections = braggdirections + + # if plot: + # from py4DSTEM.visualize import show_bragg_indexing + # show_bragg_indexing( + # self.bvm_centered, + # **bvm_vis_params, + # braggdirections = braggdirections, + # points = True + # ) + + # if returncalc: + # return braggdirections + + + + # def add_indices_to_braggvectors( + # self, + # maxPeakSpacing, + # mask = None, + # returncalc = False, + # ): + # """ + # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + # identify the indices for each peak in the PointListArray braggpeaks. + # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + # indices with the ints (h,k) and indicating whether the peak was successfully indexed + # or not with the bool index_mask. If `mask` is specified, only the locations where + # mask is True are indexed. + + # Args: + # maxPeakSpacing (float): Maximum distance from the ideal lattice points + # to include a peak for indexing + # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + # relative to the `braggpeaks` PointListArray + # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + # locations should be indexed. This can be used to index different regions of + # the scan with different lattices + # """ + # from py4DSTEM.process.latticevectors import add_indices_to_braggvectors + + # bragg_peaks_indexed = add_indices_to_braggvectors( + # self.vectors, + # self.braggdirections, + # maxPeakSpacing = maxPeakSpacing, + # qx_shift = self.Qshape[0]/2, + # qy_shift = self.Qshape[1]/2, + # ) + + # self.bragg_peaks_indexed = bragg_peaks_indexed + + # if returncalc: + # return bragg_peaks_indexed + + + # def fit_lattice_vectors_all_DPs(self, returncalc = False): + # """ + # Fits lattice vectors g1,g2 to each diffraction pattern in braggpeaks, given some + # known (h,k) indexing. + + + # """ + + # from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs + # g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_peaks_indexed) + # self.g1g2_map = g1g2_map + # if returncalc: + # return g1g2_map + + # def get_strain_from_reference_region(self, mask, returncalc = False): + # """ + # Gets a strain map from the reference region of real space specified by mask and the + # lattice vector map g1g2_map. + + # Args: + # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions + # wherever mask==True + + # """ + # from py4DSTEM.process.latticevectors import get_strain_from_reference_region + + # strainmap_median_g1g2 = get_strain_from_reference_region( + # self.g1g2_map, + # mask = mask, + # ) + + # self.strainmap_median_g1g2 = strainmap_median_g1g2 + + # if returncalc: + # return strainmap_median_g1g2 + + + # def get_strain_from_reference_g1g2(self, mask, returncalc = False): + # """ + # Gets a strain map from the reference lattice vectors g1,g2 and lattice vector map + # g1g2_map. + + + # Args: + # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions + # wherever mask==True + + # """ + # from py4DSTEM.process.latticevectors import get_reference_g1g2 + # g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + + # from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 + # strainmap_reference_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) - """ - - from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs - g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_peaks_indexed) - self.g1g2_map = g1g2_map - if returncalc: - return g1g2_map - - def get_strain_from_reference_region(self, mask, returncalc = False): - """ - Gets a strain map from the reference region of real space specified by mask and the - lattice vector map g1g2_map. - - Args: - mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - wherever mask==True - - """ - from py4DSTEM.process.latticevectors import get_strain_from_reference_region - - strainmap_median_g1g2 = get_strain_from_reference_region( - self.g1g2_map, - mask = mask, - ) - - self.strainmap_median_g1g2 = strainmap_median_g1g2 - - if returncalc: - return strainmap_median_g1g2 - - - def get_strain_from_reference_g1g2(self, mask, returncalc = False): - """ - Gets a strain map from the reference lattice vectors g1,g2 and lattice vector map - g1g2_map. + # self.strainmap_reference_g1g2 = strainmap_reference_g1g2 + + # if returncalc: + # return strainmap_reference_g1g2 + + # def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, flip_theta = False): + # """ + # Starting from a strain map defined with respect to the xy coordinate system of + # diffraction space, i.e. where exx and eyy are the compression/tension along the Qx + # and Qy directions, respectively, get a strain map defined with respect to some other + # right-handed coordinate system, in which the x-axis is oriented along (xaxis_x, + # xaxis_y). + + # Args: + # g_referencce (tupe): reference coordinate system for xaxis_x and xaxis_y + # """ + # assert mode in ("median","reference") + # if g_reference is None: + # g_reference = np.subtract(self.g1, self.g2) - Args: - mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - wherever mask==True + # from py4DSTEM.process.latticevectors import get_rotated_strain_map - """ - from py4DSTEM.process.latticevectors import get_reference_g1g2 - g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + # if mode == "median": + # strainmap_raw = self.strainmap_median_g1g2 + # elif mode == "reference": + # strainmap_raw = self.strainmap_reference_g1g2 - from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 - strainmap_reference_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + # strainmap = get_rotated_strain_map( + # strainmap_raw, + # xaxis_x = g_reference[0], + # xaxis_y = g_reference[1], + # flip_theta = flip_theta + # ) - self.strainmap_reference_g1g2 = strainmap_reference_g1g2 - - if returncalc: - return strainmap_reference_g1g2 - - def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, flip_theta = False): - """ - Starting from a strain map defined with respect to the xy coordinate system of - diffraction space, i.e. where exx and eyy are the compression/tension along the Qx - and Qy directions, respectively, get a strain map defined with respect to some other - right-handed coordinate system, in which the x-axis is oriented along (xaxis_x, - xaxis_y). - - Args: - g_referencce (tupe): reference coordinate system for xaxis_x and xaxis_y - """ - - assert mode in ("median","reference") - if g_reference is None: - g_reference = np.subtract(self.g1, self.g2) - - from py4DSTEM.process.latticevectors import get_rotated_strain_map - - if mode == "median": - strainmap_raw = self.strainmap_median_g1g2 - elif mode == "reference": - strainmap_raw = self.strainmap_reference_g1g2 - - strainmap = get_rotated_strain_map( - strainmap_raw, - xaxis_x = g_reference[0], - xaxis_y = g_reference[1], - flip_theta = flip_theta - ) - - if returncalc: - return strainmap + # if returncalc: + # return strainmap def mask_in_Q( diff --git a/py4DSTEM/process/latticevectors/strain.py b/py4DSTEM/process/latticevectors/strain.py index 518f38885..7a586bd69 100644 --- a/py4DSTEM/process/latticevectors/strain.py +++ b/py4DSTEM/process/latticevectors/strain.py @@ -172,18 +172,20 @@ def get_rotated_strain_map(unrotated_strain_map, xaxis_x, xaxis_y, flip_theta): sint2 = sint**2 Rx,Ry = unrotated_strain_map.get_slice('e_xx').data.shape - rotated_strain_map = RealSlice(data=np.zeros((Rx,Ry,5)), - slicelabels=['e_xx','e_xy','e_yy','theta','mask'], - name=unrotated_strain_map.name+"_rotated".format(np.degrees(theta))) + rotated_strain_map = RealSlice( + data=np.zeros((5, Rx,Ry)), + slicelabels=['e_xx','e_xy','e_yy','theta','mask'], + name=unrotated_strain_map.name+"_rotated".format(np.degrees(theta)) + ) - rotated_strain_map.data[:,:,0] = cost2*unrotated_strain_map.get_slice('e_xx').data - 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + sint2*unrotated_strain_map.get_slice('e_yy').data - rotated_strain_map.data[:,:,1] = cost*sint*(unrotated_strain_map.get_slice('e_xx').data-unrotated_strain_map.get_slice('e_yy').data) + (cost2-sint2)*unrotated_strain_map.get_slice('e_xy').data - rotated_strain_map.data[:,:,2] = sint2*unrotated_strain_map.get_slice('e_xx').data + 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + cost2*unrotated_strain_map.get_slice('e_yy').data + rotated_strain_map.data[0,:,:] = cost2*unrotated_strain_map.get_slice('e_xx').data - 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + sint2*unrotated_strain_map.get_slice('e_yy').data + rotated_strain_map.data[1,:,:] = cost*sint*(unrotated_strain_map.get_slice('e_xx').data-unrotated_strain_map.get_slice('e_yy').data) + (cost2-sint2)*unrotated_strain_map.get_slice('e_xy').data + rotated_strain_map.data[2,:,:] = sint2*unrotated_strain_map.get_slice('e_xx').data + 2*cost*sint*unrotated_strain_map.get_slice('e_xy').data + cost2*unrotated_strain_map.get_slice('e_yy').data if flip_theta == True: - rotated_strain_map.data[:,:,3] = -unrotated_strain_map.get_slice('theta').data + rotated_strain_map.data[3,:,:] = -unrotated_strain_map.get_slice('theta').data else: - rotated_strain_map.data[:,:,3] = unrotated_strain_map.get_slice('theta').data - rotated_strain_map.data[:,:,4] = unrotated_strain_map.get_slice('mask').data + rotated_strain_map.data[3,:,:] = unrotated_strain_map.get_slice('theta').data + rotated_strain_map.data[4,:,:] = unrotated_strain_map.get_slice('mask').data return rotated_strain_map diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index a275f9e6b..0424e92e0 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -385,21 +385,57 @@ def fit_lattice_vectors( def get_strain( self, mask=None, + g_reference=None, + flip_theta=False, returncalc=False, **kwargs ): - """ """ + """ + mask: nd.array (bool) + Use lattice vectors from g1g2_map scan positions + wherever mask==True. If mask is None gets median strain + map from entire field of view. If mask is not None, gets + reference g1 and g2 from region and then calculates strain. + g_reference: nd.array of form [x,y] + G_reference (tupe): reference coordinate system for + xaxis_x and xaxis_y + flip_theta: bool + If True, flips rotation coordinate system + returncal: bool + It True, returns rotated map + """ if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") - from py4DSTEM.process.latticevectors import get_strain_from_reference_region + from py4DSTEM.process.latticevectors import get_strain_from_reference_region - strainmap_median_g1g2 = get_strain_from_reference_region( - self.g1g2_map, - mask=mask, + strainmap_g1g2 = get_strain_from_reference_region( + self.g1g2_map, + mask=mask, + ) + else: + from py4DSTEM.process.latticevectors import get_reference_g1g2 + g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) + + from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 + strainmap_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + + self.strainmap_g1g2 = strainmap_g1g2 + + if g_reference is None: + g_reference = np.subtract(self.g1, self.g2) + + print(g_reference) + from py4DSTEM.process.latticevectors import get_rotated_strain_map + + strainmap_rotated = get_rotated_strain_map( + self.strainmap_g1g2, + xaxis_x = g_reference[0], + xaxis_y = g_reference[1], + flip_theta = flip_theta ) - self.strainmap_median_g1g2 = strainmap_median_g1g2 + self.strainmap_rotated = strainmap_rotated from py4DSTEM.visualize import show_strain figsize = kwargs.pop("figsize", (14, 4)) @@ -410,7 +446,7 @@ def get_strain( axes_plots = kwargs.pop("axes_plots",()) fig, ax = show_strain( - strainmap_median_g1g2, + self.strainmap_rotated, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, @@ -422,10 +458,13 @@ def get_strain( ) if not np.all(mask == True): - for axs in ax.flatten(): - axs.imshow(mask, alpha = 0.2, cmap = "binary") + ax[0][0].imshow(mask, alpha = 0.2, cmap = "binary") + ax[0][1].imshow(mask, alpha = 0.2, cmap = "binary") + ax[1][0].imshow(mask, alpha = 0.2, cmap = "binary") + ax[1][1].imshow(mask, alpha = 0.2, cmap = "binary") + if returncalc: - return strainmap_median_g1g2 + return self.strainmap_rotated def show_lattice_vectors( ar, @@ -519,7 +558,9 @@ def show_bragg_indexing( else: plt.show() return - + + # def copy(): + # # TODO - copy method # def index_bragg_directions(x0, y0, gx, gy, g1, g2): # """ @@ -573,81 +614,81 @@ def show_bragg_indexing( # return h,k, bragg_directions -def add_indices_to_braggvectors( - braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None -): - """ - Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - identify the indices for each peak in the PointListArray braggpeaks. - Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - indices with the ints (h,k) and indicating whether the peak was successfully indexed - or not with the bool index_mask. If `mask` is specified, only the locations where - mask is True are indexed. - - Args: - braggpeaks (PointListArray): the braggpeaks to index. Must contain - the coordinates 'qx', 'qy', and 'intensity' - lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. - Must contain the coordinates 'qx', 'qy', 'h', and 'k' - maxPeakSpacing (float): Maximum distance from the ideal lattice points - to include a peak for indexing - qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - relative to the `braggpeaks` PointListArray - mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - locations should be indexed. This can be used to index different regions of - the scan with different lattices - - Returns: - (PointListArray): The original braggpeaks pointlistarray, with new coordinates - 'h', 'k', containing the indices of each indexable peak. - """ +# def add_indices_to_braggvectors( +# braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None +# ): +# """ +# Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, +# identify the indices for each peak in the PointListArray braggpeaks. +# Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus +# three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak +# indices with the ints (h,k) and indicating whether the peak was successfully indexed +# or not with the bool index_mask. If `mask` is specified, only the locations where +# mask is True are indexed. + +# Args: +# braggpeaks (PointListArray): the braggpeaks to index. Must contain +# the coordinates 'qx', 'qy', and 'intensity' +# lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. +# Must contain the coordinates 'qx', 'qy', 'h', and 'k' +# maxPeakSpacing (float): Maximum distance from the ideal lattice points +# to include a peak for indexing +# qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList +# relative to the `braggpeaks` PointListArray +# mask (bool): Boolean mask, same shape as the pointlistarray, indicating which +# locations should be indexed. This can be used to index different regions of +# the scan with different lattices + +# Returns: +# (PointListArray): The original braggpeaks pointlistarray, with new coordinates +# 'h', 'k', containing the indices of each indexable peak. +# """ - assert isinstance(braggpeaks, PointListArray) - assert np.all( - [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] - ) - assert isinstance(lattice, PointList) - assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - - if mask is None: - mask = np.ones(braggpeaks.shape, dtype=bool) - - assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" - assert mask.dtype == bool, "mask must be boolean" - - indexed_braggpeaks = braggpeaks.copy() - - # add the coordinates if they don't exist - if not ("h" in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) - if not ("k" in braggpeaks.dtype.names): - indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - - # loop over all the scan positions - for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): - if mask[Rx, Ry]: - pl = indexed_braggpeaks.get_pointlist(Rx, Ry) - rm_peak_mask = np.zeros(pl.length, dtype=bool) - - for i in range(pl.length): - r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( - pl.data["qy"][i] - lattice.data["qy"] + qy_shift - ) ** 2 - ind = np.argmin(r2) - if r2[ind] <= maxPeakSpacing**2: - pl.data["h"][i] = lattice.data["h"][ind] - pl.data["k"][i] = lattice.data["k"][ind] - else: - rm_peak_mask[i] = True - pl.remove(rm_peak_mask) - - indexed_braggpeaks.name = braggpeaks.name + "_indexed" - return indexed_braggpeaks +# assert isinstance(braggpeaks, PointListArray) +# assert np.all( +# [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] +# ) +# assert isinstance(lattice, PointList) +# assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) + +# if mask is None: +# mask = np.ones(braggpeaks.shape, dtype=bool) + +# assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" +# assert mask.dtype == bool, "mask must be boolean" + +# indexed_braggpeaks = braggpeaks.copy() + +# # add the coordinates if they don't exist +# if not ("h" in braggpeaks.dtype.names): +# indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) +# if not ("k" in braggpeaks.dtype.names): +# indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) + +# # loop over all the scan positions +# for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): +# if mask[Rx, Ry]: +# pl = indexed_braggpeaks.get_pointlist(Rx, Ry) +# rm_peak_mask = np.zeros(pl.length, dtype=bool) + +# for i in range(pl.length): +# r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( +# pl.data["qy"][i] - lattice.data["qy"] + qy_shift +# ) ** 2 +# ind = np.argmin(r2) +# if r2[ind] <= maxPeakSpacing**2: +# pl.data["h"][i] = lattice.data["h"][ind] +# pl.data["k"][i] = lattice.data["k"][ind] +# else: +# rm_peak_mask[i] = True +# pl.remove(rm_peak_mask) + +# indexed_braggpeaks.name = braggpeaks.name + "_indexed" +# return indexed_braggpeaks # IO methods - # TODO - copy method + # read @classmethod From e5b9a8b5b0a9daf21f9133d6fa76f6a52cd5dffa Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 11:47:35 -0700 Subject: [PATCH 343/362] strain copy --- py4DSTEM/process/strain.py | 324 +++++++++++++++++++------------------ 1 file changed, 165 insertions(+), 159 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 0424e92e0..3ce202e4b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -25,7 +25,7 @@ def __init__(self, braggvectors: BraggVectors, name: Optional[str] = "strainmap" """ assert isinstance( braggvectors, BraggVectors - ), f"braggvectors myst be BraggVectors, not type {type(braggvectors)}" + ), f"braggvectors must be BraggVectors, not type {type(braggvectors)}" # initialize as a RealSlice RealSlice.__init__( @@ -383,27 +383,27 @@ def fit_lattice_vectors( braggdirections, bragg_vectors_indexed, g1g2_map def get_strain( - self, - mask=None, - g_reference=None, - flip_theta=False, - returncalc=False, - **kwargs + self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs ): - """ - mask: nd.array (bool) + """ + mask: nd.array (bool) Use lattice vectors from g1g2_map scan positions wherever mask==True. If mask is None gets median strain - map from entire field of view. If mask is not None, gets + map from entire field of view. If mask is not None, gets reference g1 and g2 from region and then calculates strain. g_reference: nd.array of form [x,y] - G_reference (tupe): reference coordinate system for + G_reference (tupe): reference coordinate system for xaxis_x and xaxis_y flip_theta: bool If True, flips rotation coordinate system returncal: bool It True, returns rotated map """ + # check the calstate + assert ( + self.calstate == self.braggvectors.calstate + ), "The calibration state has changed! To resync the calibration state, use `.reset_calstate`." + if mask is None: mask = np.ones(self.g1g2_map.shape, dtype="bool") @@ -415,38 +415,42 @@ def get_strain( ) else: from py4DSTEM.process.latticevectors import get_reference_g1g2 - g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) - + + g1_ref, g2_ref = get_reference_g1g2(self.g1g2_map, mask) + from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 - strainmap_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) + + strainmap_g1g2 = get_strain_from_reference_g1g2( + self.g1g2_map, g1_ref, g2_ref + ) self.strainmap_g1g2 = strainmap_g1g2 if g_reference is None: g_reference = np.subtract(self.g1, self.g2) - print(g_reference) from py4DSTEM.process.latticevectors import get_rotated_strain_map strainmap_rotated = get_rotated_strain_map( self.strainmap_g1g2, - xaxis_x = g_reference[0], - xaxis_y = g_reference[1], - flip_theta = flip_theta + xaxis_x=g_reference[0], + xaxis_y=g_reference[1], + flip_theta=flip_theta, ) - self.strainmap_rotated = strainmap_rotated - + self.data = strainmap_rotated + from py4DSTEM.visualize import show_strain + figsize = kwargs.pop("figsize", (14, 4)) vrange_exx = kwargs.pop("vrange_exx", [-2.0, 2.0]) vrange_theta = kwargs.pop("vrange_theta", [-2.0, 2.0]) ticknumber = kwargs.pop("ticknumber", 3) - bkgrd = kwargs.pop("bkgrd", False) - axes_plots = kwargs.pop("axes_plots",()) + bkgrd = kwargs.pop("bkgrd", False) + axes_plots = kwargs.pop("axes_plots", ()) fig, ax = show_strain( - self.strainmap_rotated, + self.data, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, @@ -454,15 +458,15 @@ def get_strain( bkgrd=bkgrd, figsize=figsize, **kwargs, - returnfig = True, + returnfig=True, ) - if not np.all(mask == True): - ax[0][0].imshow(mask, alpha = 0.2, cmap = "binary") - ax[0][1].imshow(mask, alpha = 0.2, cmap = "binary") - ax[1][0].imshow(mask, alpha = 0.2, cmap = "binary") - ax[1][1].imshow(mask, alpha = 0.2, cmap = "binary") - + if not np.all(mask == True): + ax[0][0].imshow(mask, alpha=0.2, cmap="binary") + ax[0][1].imshow(mask, alpha=0.2, cmap="binary") + ax[1][0].imshow(mask, alpha=0.2, cmap="binary") + ax[1][1].imshow(mask, alpha=0.2, cmap="binary") + if returncalc: return self.strainmap_rotated @@ -558,137 +562,139 @@ def show_bragg_indexing( else: plt.show() return - - # def copy(): - # # TODO - copy method - -# def index_bragg_directions(x0, y0, gx, gy, g1, g2): -# """ -# From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of -# lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the -# reciprocal lattice directions. - -# The approach is to solve the matrix equation -# ``alpha = beta * M`` -# where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, -# beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the -# h,k indices. - -# Args: -# x0 (float): x-coord of origin -# y0 (float): y-coord of origin -# gx (1d array): x-coord of the reciprocal lattice vectors -# gy (1d array): y-coord of the reciprocal lattice vectors -# g1 (2-tuple of floats): g1x,g1y -# g2 (2-tuple of floats): g2x,g2y - -# Returns: -# (3-tuple) A 3-tuple containing: - -# * **h**: *(ndarray of ints)* first index of the bragg directions -# * **k**: *(ndarray of ints)* second index of the bragg directions -# * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the -# indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y -# coords 'h' and 'k' contain h and k. -# """ -# # Get beta, the matrix of lattice vectors -# beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - -# # Get alpha, the matrix of measured bragg angles -# alpha = np.vstack([gx-x0,gy-y0]) - -# # Calculate M, the matrix of peak positions -# M = lstsq(beta, alpha, rcond=None)[0].T -# M = np.round(M).astype(int) - -# # Get h,k -# h = M[:,0] -# k = M[:,1] - -# # Store in a PointList -# coords = [('qx',float),('qy',float),('h',int),('k',int)] -# temp_array = np.zeros([], dtype = coords) -# bragg_directions = PointList(data = temp_array) -# bragg_directions.add_data_by_field((gx,gy,h,k)) - -# return h,k, bragg_directions - - -# def add_indices_to_braggvectors( -# braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None -# ): -# """ -# Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, -# identify the indices for each peak in the PointListArray braggpeaks. -# Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus -# three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak -# indices with the ints (h,k) and indicating whether the peak was successfully indexed -# or not with the bool index_mask. If `mask` is specified, only the locations where -# mask is True are indexed. - -# Args: -# braggpeaks (PointListArray): the braggpeaks to index. Must contain -# the coordinates 'qx', 'qy', and 'intensity' -# lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. -# Must contain the coordinates 'qx', 'qy', 'h', and 'k' -# maxPeakSpacing (float): Maximum distance from the ideal lattice points -# to include a peak for indexing -# qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList -# relative to the `braggpeaks` PointListArray -# mask (bool): Boolean mask, same shape as the pointlistarray, indicating which -# locations should be indexed. This can be used to index different regions of -# the scan with different lattices - -# Returns: -# (PointListArray): The original braggpeaks pointlistarray, with new coordinates -# 'h', 'k', containing the indices of each indexable peak. -# """ - -# assert isinstance(braggpeaks, PointListArray) -# assert np.all( -# [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] -# ) -# assert isinstance(lattice, PointList) -# assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - -# if mask is None: -# mask = np.ones(braggpeaks.shape, dtype=bool) - -# assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" -# assert mask.dtype == bool, "mask must be boolean" - -# indexed_braggpeaks = braggpeaks.copy() - -# # add the coordinates if they don't exist -# if not ("h" in braggpeaks.dtype.names): -# indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) -# if not ("k" in braggpeaks.dtype.names): -# indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - -# # loop over all the scan positions -# for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): -# if mask[Rx, Ry]: -# pl = indexed_braggpeaks.get_pointlist(Rx, Ry) -# rm_peak_mask = np.zeros(pl.length, dtype=bool) - -# for i in range(pl.length): -# r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( -# pl.data["qy"][i] - lattice.data["qy"] + qy_shift -# ) ** 2 -# ind = np.argmin(r2) -# if r2[ind] <= maxPeakSpacing**2: -# pl.data["h"][i] = lattice.data["h"][ind] -# pl.data["k"][i] = lattice.data["k"][ind] -# else: -# rm_peak_mask[i] = True -# pl.remove(rm_peak_mask) - -# indexed_braggpeaks.name = braggpeaks.name + "_indexed" -# return indexed_braggpeaks - # IO methods + def copy(self, name=None): + name = name if name is not None else self.name + "_copy" + strainmap_copy = StrainMap(self.braggvectors) + + for k in self.metadata.keys(): + strainmap_copy.metadata = self.metadata[k].copy() + return strainmap_copy + + # def index_bragg_directions(x0, y0, gx, gy, g1, g2): + # """ + # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of + # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the + # reciprocal lattice directions. + + # The approach is to solve the matrix equation + # ``alpha = beta * M`` + # where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, + # beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the + # h,k indices. + + # Args: + # x0 (float): x-coord of origin + # y0 (float): y-coord of origin + # gx (1d array): x-coord of the reciprocal lattice vectors + # gy (1d array): y-coord of the reciprocal lattice vectors + # g1 (2-tuple of floats): g1x,g1y + # g2 (2-tuple of floats): g2x,g2y + + # Returns: + # (3-tuple) A 3-tuple containing: + + # * **h**: *(ndarray of ints)* first index of the bragg directions + # * **k**: *(ndarray of ints)* second index of the bragg directions + # * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the + # indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y + # coords 'h' and 'k' contain h and k. + # """ + # # Get beta, the matrix of lattice vectors + # beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) + + # # Get alpha, the matrix of measured bragg angles + # alpha = np.vstack([gx-x0,gy-y0]) + + # # Calculate M, the matrix of peak positions + # M = lstsq(beta, alpha, rcond=None)[0].T + # M = np.round(M).astype(int) + + # # Get h,k + # h = M[:,0] + # k = M[:,1] + + # # Store in a PointList + # coords = [('qx',float),('qy',float),('h',int),('k',int)] + # temp_array = np.zeros([], dtype = coords) + # bragg_directions = PointList(data = temp_array) + # bragg_directions.add_data_by_field((gx,gy,h,k)) + + # return h,k, bragg_directions + + # def add_indices_to_braggvectors( + # braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None + # ): + # """ + # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, + # identify the indices for each peak in the PointListArray braggpeaks. + # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus + # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak + # indices with the ints (h,k) and indicating whether the peak was successfully indexed + # or not with the bool index_mask. If `mask` is specified, only the locations where + # mask is True are indexed. + + # Args: + # braggpeaks (PointListArray): the braggpeaks to index. Must contain + # the coordinates 'qx', 'qy', and 'intensity' + # lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. + # Must contain the coordinates 'qx', 'qy', 'h', and 'k' + # maxPeakSpacing (float): Maximum distance from the ideal lattice points + # to include a peak for indexing + # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList + # relative to the `braggpeaks` PointListArray + # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which + # locations should be indexed. This can be used to index different regions of + # the scan with different lattices + + # Returns: + # (PointListArray): The original braggpeaks pointlistarray, with new coordinates + # 'h', 'k', containing the indices of each indexable peak. + # """ + + # assert isinstance(braggpeaks, PointListArray) + # assert np.all( + # [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] + # ) + # assert isinstance(lattice, PointList) + # assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) + + # if mask is None: + # mask = np.ones(braggpeaks.shape, dtype=bool) + + # assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" + # assert mask.dtype == bool, "mask must be boolean" + + # indexed_braggpeaks = braggpeaks.copy() + + # # add the coordinates if they don't exist + # if not ("h" in braggpeaks.dtype.names): + # indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) + # if not ("k" in braggpeaks.dtype.names): + # indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) + + # # loop over all the scan positions + # for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): + # if mask[Rx, Ry]: + # pl = indexed_braggpeaks.get_pointlist(Rx, Ry) + # rm_peak_mask = np.zeros(pl.length, dtype=bool) + + # for i in range(pl.length): + # r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( + # pl.data["qy"][i] - lattice.data["qy"] + qy_shift + # ) ** 2 + # ind = np.argmin(r2) + # if r2[ind] <= maxPeakSpacing**2: + # pl.data["h"][i] = lattice.data["h"][ind] + # pl.data["k"][i] = lattice.data["k"][ind] + # else: + # rm_peak_mask[i] = True + # pl.remove(rm_peak_mask) + + # indexed_braggpeaks.name = braggpeaks.name + "_indexed" + # return indexed_braggpeaks - + # IO methods # read @classmethod From 7149d58135abc9d2ab9ad20670e5941a60c9d600 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 12:01:40 -0700 Subject: [PATCH 344/362] rotated --- py4DSTEM/process/strain.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 3ce202e4b..372ae7397 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -438,7 +438,7 @@ def get_strain( flip_theta=flip_theta, ) - self.data = strainmap_rotated + self.strainmap_rotated = strainmap_rotated from py4DSTEM.visualize import show_strain @@ -450,7 +450,7 @@ def get_strain( axes_plots = kwargs.pop("axes_plots", ()) fig, ax = show_strain( - self.data, + self.strainmap_rotated, vrange_exx=vrange_exx, vrange_theta=vrange_theta, ticknumber=ticknumber, From 80e80b9cfde9473d75f5540b49e2b17ad55d69aa Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Fri, 14 Jul 2023 13:21:24 -0700 Subject: [PATCH 345/362] fix copy method --- py4DSTEM/process/strain.py | 153 +++++----------------------------- py4DSTEM/visualize/overlay.py | 22 ++--- 2 files changed, 33 insertions(+), 142 deletions(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 372ae7397..247b60a06 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -330,7 +330,7 @@ def fit_lattice_vectors( vis_params : dict additional visualization parameters passed to `show` returncalc : bool - if True, returns braggdirections, bragg_vectors_indexed, g1g2_map + if True, returns bragg_directions, bragg_vectors_indexed, g1g2_map """ # check the calstate assert ( @@ -354,7 +354,7 @@ def fit_lattice_vectors( if plot: self.show_bragg_indexing( self.bvm, - braggdirections=braggdirections, + bragg_directions=braggdirections, points=True, **vis_params, ) @@ -364,7 +364,7 @@ def fit_lattice_vectors( bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, - self.braggdirections, + self.bragg_directions, maxPeakSpacing=max_peak_spacing, qx_shift=self.braggvectors.Qshape[0] / 2, qy_shift=self.braggvectors.Qshape[1] / 2, @@ -380,7 +380,7 @@ def fit_lattice_vectors( self.g1g2_map = g1g2_map if returncalc: - braggdirections, bragg_vectors_indexed, g1g2_map + bragg_directions, bragg_vectors_indexed, g1g2_map def get_strain( self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs @@ -521,7 +521,7 @@ def show_lattice_vectors( def show_bragg_indexing( self, ar, - braggdirections, + bragg_directions, voffset=5, hoffset=0, color="w", @@ -540,13 +540,13 @@ def show_bragg_indexing( bragg_directions (PointList) the bragg scattering directions; must have coordinates 'qx','qy','h', and 'k'. Optionally may also have 'l'. """ - assert isinstance(braggdirections, PointList) + assert isinstance(bragg_directions, PointList) for k in ("qx", "qy", "h", "k"): - assert k in braggdirections.data.dtype.fields + assert k in bragg_directions.data.dtype.fields fig, ax = show(ar, returnfig=True, **kwargs) d = { - "braggdirections": braggdirections, + "bragg_directions": bragg_directions, "voffset": voffset, "hoffset": hoffset, "color": color, @@ -566,134 +566,25 @@ def show_bragg_indexing( def copy(self, name=None): name = name if name is not None else self.name + "_copy" strainmap_copy = StrainMap(self.braggvectors) + for attr in ( + "g", + "g0", + "g1", + "g2", + "calstate", + "bragg_directions", + "bragg_vectors_indexed", + "g1g2_map", + "strainmap_g1g2", + "strainmap_rotated", + ): + if hasattr(self, attr): + setattr(strainmap_copy, attr, getattr(self, attr)) for k in self.metadata.keys(): strainmap_copy.metadata = self.metadata[k].copy() return strainmap_copy - # def index_bragg_directions(x0, y0, gx, gy, g1, g2): - # """ - # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - # reciprocal lattice directions. - - # The approach is to solve the matrix equation - # ``alpha = beta * M`` - # where alpha is the 2xN array of the (x,y) coordinates of N measured bragg directions, - # beta is the 2x2 array of the two lattice vectors u,v, and M is the 2xN array of the - # h,k indices. - - # Args: - # x0 (float): x-coord of origin - # y0 (float): y-coord of origin - # gx (1d array): x-coord of the reciprocal lattice vectors - # gy (1d array): y-coord of the reciprocal lattice vectors - # g1 (2-tuple of floats): g1x,g1y - # g2 (2-tuple of floats): g2x,g2y - - # Returns: - # (3-tuple) A 3-tuple containing: - - # * **h**: *(ndarray of ints)* first index of the bragg directions - # * **k**: *(ndarray of ints)* second index of the bragg directions - # * **bragg_directions**: *(PointList)* a 4-coordinate PointList with the - # indexed bragg directions; coords 'qx' and 'qy' contain bragg_x and bragg_y - # coords 'h' and 'k' contain h and k. - # """ - # # Get beta, the matrix of lattice vectors - # beta = np.array([[g1[0],g2[0]],[g1[1],g2[1]]]) - - # # Get alpha, the matrix of measured bragg angles - # alpha = np.vstack([gx-x0,gy-y0]) - - # # Calculate M, the matrix of peak positions - # M = lstsq(beta, alpha, rcond=None)[0].T - # M = np.round(M).astype(int) - - # # Get h,k - # h = M[:,0] - # k = M[:,1] - - # # Store in a PointList - # coords = [('qx',float),('qy',float),('h',int),('k',int)] - # temp_array = np.zeros([], dtype = coords) - # bragg_directions = PointList(data = temp_array) - # bragg_directions.add_data_by_field((gx,gy,h,k)) - - # return h,k, bragg_directions - - # def add_indices_to_braggvectors( - # braggpeaks, lattice, maxPeakSpacing, qx_shift=0, qy_shift=0, mask=None - # ): - # """ - # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - # identify the indices for each peak in the PointListArray braggpeaks. - # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - # indices with the ints (h,k) and indicating whether the peak was successfully indexed - # or not with the bool index_mask. If `mask` is specified, only the locations where - # mask is True are indexed. - - # Args: - # braggpeaks (PointListArray): the braggpeaks to index. Must contain - # the coordinates 'qx', 'qy', and 'intensity' - # lattice (PointList): the positions (qx,qy) of the (h,k) lattice points. - # Must contain the coordinates 'qx', 'qy', 'h', and 'k' - # maxPeakSpacing (float): Maximum distance from the ideal lattice points - # to include a peak for indexing - # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - # relative to the `braggpeaks` PointListArray - # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - # locations should be indexed. This can be used to index different regions of - # the scan with different lattices - - # Returns: - # (PointListArray): The original braggpeaks pointlistarray, with new coordinates - # 'h', 'k', containing the indices of each indexable peak. - # """ - - # assert isinstance(braggpeaks, PointListArray) - # assert np.all( - # [name in braggpeaks.dtype.names for name in ("qx", "qy", "intensity")] - # ) - # assert isinstance(lattice, PointList) - # assert np.all([name in lattice.dtype.names for name in ("qx", "qy", "h", "k")]) - - # if mask is None: - # mask = np.ones(braggpeaks.shape, dtype=bool) - - # assert mask.shape == braggpeaks.shape, "mask must have same shape as pointlistarray" - # assert mask.dtype == bool, "mask must be boolean" - - # indexed_braggpeaks = braggpeaks.copy() - - # # add the coordinates if they don't exist - # if not ("h" in braggpeaks.dtype.names): - # indexed_braggpeaks = indexed_braggpeaks.add_fields([("h", int)]) - # if not ("k" in braggpeaks.dtype.names): - # indexed_braggpeaks = indexed_braggpeaks.add_fields([("k", int)]) - - # # loop over all the scan positions - # for Rx, Ry in tqdmnd(mask.shape[0], mask.shape[1]): - # if mask[Rx, Ry]: - # pl = indexed_braggpeaks.get_pointlist(Rx, Ry) - # rm_peak_mask = np.zeros(pl.length, dtype=bool) - - # for i in range(pl.length): - # r2 = (pl.data["qx"][i] - lattice.data["qx"] + qx_shift) ** 2 + ( - # pl.data["qy"][i] - lattice.data["qy"] + qy_shift - # ) ** 2 - # ind = np.argmin(r2) - # if r2[ind] <= maxPeakSpacing**2: - # pl.data["h"][i] = lattice.data["h"][ind] - # pl.data["k"][i] = lattice.data["k"][ind] - # else: - # rm_peak_mask[i] = True - # pl.remove(rm_peak_mask) - - # indexed_braggpeaks.name = braggpeaks.name + "_indexed" - # return indexed_braggpeaks - # IO methods # read diff --git a/py4DSTEM/visualize/overlay.py b/py4DSTEM/visualize/overlay.py index e0c87a427..7e7147a15 100644 --- a/py4DSTEM/visualize/overlay.py +++ b/py4DSTEM/visualize/overlay.py @@ -437,7 +437,7 @@ def add_bragg_index_labels(ax,d): Adds labels for indexed bragg directions to a plot, using the parameters in dict d. The dictionary d has required and optional parameters as follows: - braggdirections (req'd) (PointList) the Bragg directions. This PointList must have + bragg_directions (req'd) (PointList) the Bragg directions. This PointList must have the fields 'qx','qy','h', and 'k', and may optionally have 'l' voffset (number) vertical offset for the labels hoffset (number) horizontal offset for the labels @@ -450,12 +450,12 @@ def add_bragg_index_labels(ax,d): # handle inputs assert isinstance(ax,Axes) # bragg directions - assert('braggdirections' in d.keys()) - braggdirections = d['braggdirections'] - assert isinstance(braggdirections,PointList) + assert('bragg_directions' in d.keys()) + bragg_directions = d['bragg_directions'] + assert isinstance(bragg_directions,PointList) for k in ('qx','qy','h','k'): - assert k in braggdirections.data.dtype.fields - include_l = True if 'l' in braggdirections.data.dtype.fields else False + assert k in bragg_directions.data.dtype.fields + include_l = True if 'l' in bragg_directions.data.dtype.fields else False # offsets hoffset = d['hoffset'] if 'hoffset' in d.keys() else 0 voffset = d['voffset'] if 'voffset' in d.keys() else 5 @@ -474,20 +474,20 @@ def add_bragg_index_labels(ax,d): # add the points if points: - ax.scatter(braggdirections.data['qy'],braggdirections.data['qx'], + ax.scatter(bragg_directions.data['qy'],bragg_directions.data['qx'], color=pointcolor,s=pointsize) # add index labels - for i in range(braggdirections.length): - x,y = braggdirections.data['qx'][i],braggdirections.data['qy'][i] + for i in range(bragg_directions.length): + x,y = bragg_directions.data['qx'][i],bragg_directions.data['qy'][i] x -= voffset y += hoffset - h,k = braggdirections.data['h'][i],braggdirections.data['k'][i] + h,k = bragg_directions.data['h'][i],bragg_directions.data['k'][i] h = str(h) if h>=0 else r'$\overline{{{}}}$'.format(np.abs(h)) k = str(k) if k>=0 else r'$\overline{{{}}}$'.format(np.abs(k)) s = h+','+k if include_l: - l = braggdirections.data['l'][i] + l = bragg_directions.data['l'][i] l = str(l) if l>=0 else r'$\overline{{{}}}$'.format(np.abs(l)) s += l ax.text(y,x,s,color=color,size=size,ha='center',va='bottom') From 8263e09a3127208c1a68c5c6fbae16e5a8a12569 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Mon, 17 Jul 2023 12:14:55 -0400 Subject: [PATCH 346/362] bugfix --- py4DSTEM/process/strain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index 247b60a06..c76b429fa 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -364,7 +364,7 @@ def fit_lattice_vectors( bragg_vectors_indexed = add_indices_to_braggvectors( self.braggvectors, - self.bragg_directions, + self.braggdirections, maxPeakSpacing=max_peak_spacing, qx_shift=self.braggvectors.Qshape[0] / 2, qy_shift=self.braggvectors.Qshape[1] / 2, From cc654863611c8152963cfef8042c57f4462e5cbb Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 09:39:54 -0700 Subject: [PATCH 347/362] another origin fix --- py4DSTEM/process/calibration/origin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 2b4138a74..8821b43d0 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -134,14 +134,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit, _ = fit_2D( + popt_x, pcov_x, qx0_fit = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit, _ = fit_2D( + popt_y, pcov_y, qy0_fit = fit_2D( f, qy0_meas, robust=robust, @@ -150,7 +150,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit, _ = fit_2D( + popt_x, pcov_x, qx0_fit = fit_2D( f, qx0_meas, robust=robust, @@ -158,7 +158,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit, _ = fit_2D( + popt_y, pcov_y, qy0_fit = fit_2D( f, qy0_meas, robust=robust, From 999a5ab78e8b9e76e3b034134d10c9305e700966 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Mon, 17 Jul 2023 12:55:59 -0700 Subject: [PATCH 348/362] flake fix --- py4DSTEM/process/strain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/process/strain.py b/py4DSTEM/process/strain.py index c76b429fa..db252f75b 100644 --- a/py4DSTEM/process/strain.py +++ b/py4DSTEM/process/strain.py @@ -380,7 +380,7 @@ def fit_lattice_vectors( self.g1g2_map = g1g2_map if returncalc: - bragg_directions, bragg_vectors_indexed, g1g2_map + braggdirections, bragg_vectors_indexed, g1g2_map def get_strain( self, mask=None, g_reference=None, flip_theta=False, returncalc=False, **kwargs From 8316bc05501d2095295495b949d84f6e2e1b3e7d Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 18 Jul 2023 12:26:09 -0400 Subject: [PATCH 349/362] attempt to resolve dev/strain conflicts --- py4DSTEM/process/polar/__init__.py | 1 + py4DSTEM/process/polar/polar_datacube.py | 1 - py4DSTEM/process/polar/polar_fits.py | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/py4DSTEM/process/polar/__init__.py b/py4DSTEM/process/polar/__init__.py index ddf0a9e50..a63afff5e 100644 --- a/py4DSTEM/process/polar/__init__.py +++ b/py4DSTEM/process/polar/__init__.py @@ -1,3 +1,4 @@ from py4DSTEM.process.polar.polar_datacube import PolarDatacube from py4DSTEM.process.polar.polar_fits import fit_amorphous_ring, plot_amorphous_ring from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks, refine_peaks, plot_radial_peaks, plot_radial_background, make_orientation_histogram + diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 24e6aaf40..a4bfad383 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -3,7 +3,6 @@ from scipy.ndimage import binary_opening,binary_closing, gaussian_filter1d - class PolarDatacube: """ diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index 9d7e50290..5802ff94a 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -1,4 +1,3 @@ - import numpy as np import matplotlib.pyplot as plt # from scipy.optimize import leastsq From f8b7178dfc31e50c78cfc8f8ddb86a3a451b1f37 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:30:33 -0700 Subject: [PATCH 350/362] test for crystal_ACOM --- py4DSTEM/process/diffraction/crystal_ACOM.py | 48 ++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal_ACOM.py b/py4DSTEM/process/diffraction/crystal_ACOM.py index 4d02dcb0b..bffa5b620 100644 --- a/py4DSTEM/process/diffraction/crystal_ACOM.py +++ b/py4DSTEM/process/diffraction/crystal_ACOM.py @@ -8,6 +8,8 @@ from py4DSTEM.process.diffraction.utils import Orientation, OrientationMap, axisEqual3D from py4DSTEM.process.utils import electron_wavelength_angstrom +from warnings import warn + from numpy.linalg import lstsq try: import cupy as cp @@ -767,6 +769,18 @@ def match_orientations( num_x=bragg_peaks_array.shape[0], num_y=bragg_peaks_array.shape[1], num_matches=num_matches_return) + + #check cal state + if bragg_peaks_array.calstate['ellipse'] == False: + ellipse = False + warn('Warning: bragg peaks not elliptically calibrated') + else: + ellipse = True + if bragg_peaks_array.calstate['rotate'] == False: + rotate = False + warn('bragg peaks not rotationally calibrated') + else: + rotate = True for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -774,9 +788,17 @@ def match_orientations( unit=" PointList", disable=not progress_bar, ): + vectors = bragg_peaks_array.get_vectors( + scan_x=rx, + scan_y=ry, + center=True, + ellipse=ellipse, + pixel=True, + rotate=rotate + ) orientation = self.match_single_pattern( - bragg_peaks_array.cal[rx, ry], + bragg_peaks=vectors, num_matches_return=num_matches_return, min_number_peaks=min_number_peaks, inversion_symmetry=inversion_symmetry, @@ -1639,6 +1661,18 @@ def calculate_strain( corr_kernel_size = self.orientation_kernel_size radius_max_2 = corr_kernel_size**2 + #check cal state + if bragg_peaks_array.calstate['ellipse'] == False: + ellipse = False + warn('bragg peaks not elliptically calibrated') + else: + ellipse = True + if bragg_peaks_array.calstate['rotate'] == False: + rotate = False + warn('bragg peaks not rotationally calibrated') + else: + rotate = True + # Loop over all probe positions for rx, ry in tqdmnd( *bragg_peaks_array.shape, @@ -1647,7 +1681,14 @@ def calculate_strain( disable=not progress_bar, ): # Get bragg peaks from experiment and reference - p = bragg_peaks_array.cal[rx,ry] + p = bragg_peaks_array.get_vectors( + scan_x=rx, + scan_y=ry, + center=True, + ellipse=ellipse, + pixel=True, + rotate=rotate + ) if p.data.shape[0] >= min_num_peaks: p_ref = self.generate_diffraction_pattern( @@ -2070,5 +2111,4 @@ def symmetry_reduce_directions( } # "-3m": ["fiber", [0, 0, 1], [90.0, 60.0]], - # "-3m": ["fiber", [0, 0, 1], [180.0, 30.0]], - + # "-3m": ["fiber", [0, 0, 1], [180.0, 30.0]], \ No newline at end of file From 763ef479133ef6f919ed06512aaba6fe460393e3 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:35:19 -0700 Subject: [PATCH 351/362] ACOM --- .../process/diffraction/crystal_calibrate.py | 35 +++++++---- py4DSTEM/process/diffraction/crystal_viz.py | 61 +++++++++++++------ py4DSTEM/process/diffraction/flowlines.py | 4 +- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/py4DSTEM/process/diffraction/crystal_calibrate.py b/py4DSTEM/process/diffraction/crystal_calibrate.py index 2d08cd03c..1b65480f5 100644 --- a/py4DSTEM/process/diffraction/crystal_calibrate.py +++ b/py4DSTEM/process/diffraction/crystal_calibrate.py @@ -24,7 +24,7 @@ def calibrate_pixel_size( k_step = 0.002, k_broadening = 0.002, fit_all_intensities = True, - set_calibration = True, + set_calibration_in_place = False, verbose = True, plot_result = False, figsize: Union[list, tuple, np.ndarray] = (12, 6), @@ -60,8 +60,13 @@ def calibrate_pixel_size( figsize (list, tuple, np.ndarray): Figure size of the plot. returnfig (bool): Return handles figure and axis - Returns: - fig, ax (handles): Optional figure and axis handles, if returnfig=True. + Returns + _______ + + + + fig, ax: handles, optional + Figure and axis handles, if returnfig=True. """ @@ -112,17 +117,21 @@ def fit_profile(k, *coefs): # Get the answer pix_size_prev = bragg_peaks.calibration.get_Q_pixel_size() - ans = pix_size_prev / scale_pixel_size + pixel_size_new = pix_size_prev / scale_pixel_size - # if requested, apply calibrations - if set_calibration: - bragg_peaks.calibration.set_Q_pixel_size( ans ) + # if requested, apply calibrations in place + if set_calibration_in_place: + bragg_peaks.calibration.set_Q_pixel_size( pixel_size_new ) bragg_peaks.calibration.set_Q_pixel_units('A^-1') - bragg_peaks.setcal() - # Output + # Output calibrated Bragg peaks + bragg_peaks_cali = bragg_peaks.copy() + bragg_peaks_cali.calibration.set_Q_pixel_size( pixel_size_new ) + bragg_peaks_cali.calibration.set_Q_pixel_units('A^-1') + + # Output pixel size if verbose: - print(f"Calibrated pixel size = {np.round(ans, decimals=8)} A^-1") + print(f"Calibrated pixel size = {np.round(pixel_size_new, decimals=8)} A^-1") # Plotting if plot_result: @@ -163,9 +172,9 @@ def fit_profile(k, *coefs): # return if returnfig and plot_result: - return ans, (fig,ax) + return bragg_peaks_cali, (fig,ax) else: - return ans + return bragg_peaks_cali @@ -463,4 +472,4 @@ def fitfun(self, k, *coefs_fit): "432": [[0, 0, 0, 3, 3, 3], [True, True, True, False, False, False]], #Cubic "-43m": [[0, 0, 0, 3, 3, 3], [True, True, True, False, False, False]], #Cubic "m-3m": [[0, 0, 0, 3, 3, 3], [True, True, True, False, False, False]], #Cubic - } + } \ No newline at end of file diff --git a/py4DSTEM/process/diffraction/crystal_viz.py b/py4DSTEM/process/diffraction/crystal_viz.py index a6074e714..a9420fee4 100644 --- a/py4DSTEM/process/diffraction/crystal_viz.py +++ b/py4DSTEM/process/diffraction/crystal_viz.py @@ -296,30 +296,48 @@ def plot_scattering_intensity( bragg_k_power=0.0, bragg_intensity_power=1.0, bragg_k_broadening=0.005, - figsize: Union[list, tuple, np.ndarray] = (12, 6), + figsize: Union[list, tuple, np.ndarray] = (10, 4), returnfig: bool = False, ): """ 1D plot of the structure factors - Args: - k_min (float): min k value for profile range. - k_max (float): max k value for profile range. - k_step (float): step size of k in profile range. - k_broadening (float): Broadening of simulated pattern. - k_power_scale (float): Scale SF intensities by k**k_power_scale. - int_power_scale (float): Scale SF intensities**int_power_scale. - int_scale (float): Scale output profile by this value. - remove_origin (bool): Remove origin from plot. - bragg_peaks (BraggVectors): Passed in bragg_peaks for comparison with simulated pattern. - bragg_k_power (float): bragg_peaks scaled by k**bragg_k_power. - bragg_intensity_power (float): bragg_peaks scaled by intensities**bragg_intensity_power. - bragg_k_broadening float): Broadening applied to bragg_peaks. - figsize (list, tuple, np.ndarray): Figure size for plot. - returnfig (bool): Return figure and axes handles if this is True. - - Returns: - fig, ax (optional) figure and axes handles + Parameters + -------- + + k_min: float + min k value for profile range. + k_max: float + max k value for profile range. + k_step: float + Step size of k in profile range. + k_broadening: float + Broadening of simulated pattern. + k_power_scale: float + Scale SF intensities by k**k_power_scale. + int_power_scale: float + Scale SF intensities**int_power_scale. + int_scale: float + Scale output profile by this value. + remove_origin: bool + Remove origin from plot. + bragg_peaks: BraggVectors + Passed in bragg_peaks for comparison with simulated pattern. + bragg_k_power: float + bragg_peaks scaled by k**bragg_k_power. + bragg_intensity_power: float + bragg_peaks scaled by intensities**bragg_intensity_power. + bragg_k_broadening: float + Broadening applied to bragg_peaks. + figsize: list, tuple, np.ndarray + Figure size for plot. + returnfig (bool): + Return figure and axes handles if this is True. + + Returns + -------- + fig, ax (optional) + figure and axes handles """ # k coordinates @@ -916,6 +934,9 @@ def plot_diffraction_pattern( ax.set_ylabel("$q_x$ [Å$^{-1}$]") if plot_range_kx_ky is not None: + plot_range_kx_ky = np.array(plot_range_kx_ky) + if plot_range_kx_ky.ndim == 0: + plot_range_kx_ky = np.array((plot_range_kx_ky,plot_range_kx_ky)) ax.set_xlim((-plot_range_kx_ky[0], plot_range_kx_ky[0])) ax.set_ylim((-plot_range_kx_ky[1], plot_range_kx_ky[1])) else: @@ -1859,4 +1880,4 @@ def plot_ring_pattern( plt.show() if returnfig: - return fig, ax + return fig, ax \ No newline at end of file diff --git a/py4DSTEM/process/diffraction/flowlines.py b/py4DSTEM/process/diffraction/flowlines.py index c2fa224fa..a483740ff 100644 --- a/py4DSTEM/process/diffraction/flowlines.py +++ b/py4DSTEM/process/diffraction/flowlines.py @@ -15,7 +15,7 @@ def make_orientation_histogram( - bragg_peaks: PointList = None, + bragg_peaks: PointListArray = None, radial_ranges: np.ndarray = None, orientation_map = None, orientation_ind: int = 0, @@ -1143,4 +1143,4 @@ def set_intensity(orient,xy_t_int): mode=['clip','clip','wrap']) orient.ravel()[inds_1D] = orient.ravel()[inds_1D] + xy_t_int[:,3]*( dx)*( dy)*( dt) - return orient + return orient \ No newline at end of file From 542470986f4a970bb3669bc9f2d3a64771208cb0 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:39:43 -0700 Subject: [PATCH 352/362] polar --- py4DSTEM/process/polar/__init__.py | 3 +- py4DSTEM/process/polar/polar_datacube.py | 89 +++++++++++++++--------- py4DSTEM/process/polar/polar_fits.py | 40 ++++++++--- 3 files changed, 88 insertions(+), 44 deletions(-) diff --git a/py4DSTEM/process/polar/__init__.py b/py4DSTEM/process/polar/__init__.py index a63afff5e..79e13a054 100644 --- a/py4DSTEM/process/polar/__init__.py +++ b/py4DSTEM/process/polar/__init__.py @@ -1,4 +1,3 @@ from py4DSTEM.process.polar.polar_datacube import PolarDatacube from py4DSTEM.process.polar.polar_fits import fit_amorphous_ring, plot_amorphous_ring -from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks, refine_peaks, plot_radial_peaks, plot_radial_background, make_orientation_histogram - +from py4DSTEM.process.polar.polar_peaks import find_peaks_single_pattern, find_peaks, refine_peaks, plot_radial_peaks, plot_radial_background, make_orientation_histogram \ No newline at end of file diff --git a/py4DSTEM/process/polar/polar_datacube.py b/py4DSTEM/process/polar/polar_datacube.py index 196d1e02d..cb206c961 100644 --- a/py4DSTEM/process/polar/polar_datacube.py +++ b/py4DSTEM/process/polar/polar_datacube.py @@ -3,6 +3,7 @@ from scipy.ndimage import binary_opening,binary_closing, gaussian_filter1d + class PolarDatacube: """ @@ -20,7 +21,7 @@ def __init__( mask = None, mask_thresh = 0.1, ellipse = True, - two_fold_rotation = False, + two_fold_symmetry = False, ): """ Parameters @@ -28,14 +29,15 @@ def __init__( datacube : DataCube The datacube in cartesian coordinates qmin : number - Minumum radius of the polar transformation + Minumum radius of the polar transformation, in pixels qmax : number or None - Maximum radius of the polar transformation + Maximum radius of the polar transformation, in pixels qstep : number - Width of radial bins + Width of radial bins, in pixels n_annular : integer Number of bins in the annular direction. Bins will each - have a width of 360/num_annular_bins, in degrees + have a width of 360/n_annular, or 180/n_annular if + two_fold_rotation is set to True, in degrees qscale : number or None Radial scaling power to apply to polar transform mask : boolean array @@ -48,9 +50,10 @@ def __init__( performs an elliptic transform iff elliptic calibrations are available. two_fold_rotation : bool - Setting to True computes the transform mod(theta,pi), i.e. assumes all patterns - posess two-fold rotation (Friedel symmetry). The output angular range in this case - becomes [0, pi) as opposed to the default of [0,2*pi). + Setting to True computes the transform mod(theta,pi), i.e. assumes + all patterns possess two-fold rotation (Friedel symmetry). The + output angular range in this case becomes [0, pi) as opposed to the + default of [0,2*pi). """ # attach datacube @@ -67,17 +70,12 @@ def __init__( # setup sampling - # annular range, depending on if polar transform spans pi or 2*pi - if two_fold_rotation: - self._annular_range = np.pi - else: - self._annular_range = 2.0 * np.pi - # polar self._qscale = qscale if qmax is None: qmax = np.min(self._datacube.Qshape) / np.sqrt(2) - self.set_annular_bins(n_annular) + self._n_annular = n_annular + self.two_fold_symmetry = two_fold_symmetry #implicitly calls set_annular_bins self.set_radial_bins(qmin,qmax,qstep) # cartesian @@ -101,6 +99,16 @@ def __init__( plot_FEM_global, calculate_FEM_local, ) + from py4DSTEM.process.polar.polar_peaks import ( + find_peaks_single_pattern, + find_peaks, + refine_peaks_local, + refine_peaks, + plot_radial_peaks, + plot_radial_background, + model_radial_background, + make_orientation_histogram, + ) # sampling methods + properties @@ -176,6 +184,18 @@ def annular_bins(self): @property def annular_step(self): return self._annular_step + @property + def two_fold_symmetry(self): + return self._two_fold_symmetry + @two_fold_symmetry.setter + def two_fold_symmetry(self,x): + assert(isinstance(x,bool)), f"two_fold_symmetry must be boolean, not type {type(x)}" + self._two_fold_symmetry = x + if x: + self._annular_range = np.pi + else: + self._annular_range = 2 * np.pi + self.set_annular_bins(self._n_annular) @property def n_annular(self): @@ -195,8 +215,22 @@ def set_polar_shape(self): # set KDE params self._annular_bin_step = 1 / (self._annular_step * (self.radial_bins + self.qstep * 0.5)) self._sigma_KDE = self._annular_bin_step * 0.5 + # set array indices + self._annular_indices = np.arange(self.polar_shape[0]).astype(int) + self._radial_indices = np.arange(self.polar_shape[1]).astype(int) + # coordinate grid properties + @property + def tt(self): + return self._annular_bins + @property + def tt_deg(self): + return self._annular_bins * 180/np.pi + @property + def qq(self): + return self.radial_bins * self.calibration.get_Q_pixel_size() + # scaling property @@ -442,6 +476,7 @@ def _transform( ) return ans elif returnval == 'nan': + ans[mask_bool] = np.nan return ans elif returnval == 'all': return ans, ans_norm, norm_array, mask_bool @@ -472,7 +507,7 @@ def _transform_array( # get polar coords rr = np.sqrt(x**2 + y**2) tt = np.mod( - np.arctan2(y, x) - np.pi/2, + np.arctan2(y, x), self._polarcube._annular_range) # elliptical @@ -480,21 +515,12 @@ def _transform_array( # unpack ellipse a,b,theta = ellipse - # transformation matrix (elliptic cartesian -> circular cartesian) - A = (a/b)*np.cos(theta) - B = -np.sin(theta) - C = (a/b)*np.sin(theta) - D = np.cos(theta) - det = 1 / (A*D - B*C) - - # get circular cartesian coords - xc = x*D - y*B - yc = -x*C + y*A - - # get polar coords - rr = det * np.hypot(xc,yc) + # Get polar coords + xc = x*np.cos(theta) + y*np.sin(theta) + yc = (y*np.cos(theta) - x*np.sin(theta))*(a/b) + rr = (b/a) * np.hypot(xc,yc) tt = np.mod( - np.arctan2(yc,xc) - np.pi/2, + np.arctan2(yc,xc) + theta, self._polarcube._annular_range) # transform to bin sampling @@ -562,5 +588,4 @@ def __repr__(self): space = ' '*len(self.__class__.__name__)+' ' string = f"{self.__class__.__name__}( " string += "Retrieves the diffraction pattern at scan position (x,y) in polar coordinates when sliced with [x,y]." - return string - + return string \ No newline at end of file diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index a4fdaaa2b..b92b2b7ba 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -1,3 +1,4 @@ + import numpy as np import matplotlib.pyplot as plt # from scipy.optimize import leastsq @@ -6,13 +7,14 @@ def fit_amorphous_ring( im, - center, - radial_range, + center = None, + radial_range = None, coefs = None, + mask_dp = None, show_fit_mask = False, verbose = False, plot_result = True, - plot_log_scale = True, + plot_log_scale = False, plot_int_scale = (-3,3), figsize = (8,8), return_all_coefs = True, @@ -26,9 +28,15 @@ def fit_amorphous_ring( im: np.array 2D image array to perform fitting on center: np.array - (x,y) center coordinates for fitting mask + (x,y) center coordinates for fitting mask. If not specified + by the user, we will assume the center coordinate is (im.shape-1)/2. radial_range: np.array - (radius_inner, radius_outer) radial range to perform fitting over + (radius_inner, radius_outer) radial range to perform fitting over. + If not specified by the user, we will assume (im.shape[0]/4,im.shape[0]/2). + coefs: np.array (optional) + Array containing initial fitting coefficients for the amorphous fit. + mask_dp: np.array + Dark field mask for fitting, in addition to the radial range specified above. show_fit_mask: bool Set to true to preview the fitting mask and initial guess for the ellipse params verbose: bool @@ -52,6 +60,14 @@ def fit_amorphous_ring( 11 parameter elliptic fit coefficients """ + # Default values + if center is None: + center = np.array(( + (im.shape[0]-1)/2, + (im.shape[1]-1)/2)) + if radial_range is None: + radial_range = (im.shape[0]/4, im.shape[0]/2) + # coordinates xa,ya = np.meshgrid( np.arange(im.shape[0]), @@ -65,6 +81,9 @@ def fit_amorphous_ring( ra2 >= radial_range[0]**2, ra2 <= radial_range[1]**2, ) + if mask_dp is not None: + # Logical AND the radial mask with the user-provided mask + mask = np.logical_and(mask, mask_dp) vals = im[mask] basis = np.vstack((xa[mask],ya[mask])) @@ -117,9 +136,11 @@ def fit_amorphous_ring( int_range = ( int_med + plot_int_scale[0]*int_std, int_med + plot_int_scale[1]*int_std) - im_plot = np.tile(np.clip( - (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), - 0,1),(1,1,3)) + im_plot = np.tile( + np.clip( + (np.log(im[:,:,None]) - int_range[0]) / (int_range[1] - int_range[0]), + 0,1), + (1,1,3)) else: int_med = np.median(vals) @@ -345,5 +366,4 @@ def amorphous_model(basis, *coefs): sub = np.logical_not(sub) int_model[sub] += int12*np.exp(dr2[sub]/(-2*sigma2**2)) - return int_model - + return int_model \ No newline at end of file From fd7c50e6d218810ee3e5bd4bfe16d9844039e596 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:40:18 -0700 Subject: [PATCH 353/362] multislice --- py4DSTEM/process/phase/iterative_multislice_ptychography.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/phase/iterative_multislice_ptychography.py b/py4DSTEM/process/phase/iterative_multislice_ptychography.py index 1e9bd2cbb..92f8c0bf3 100644 --- a/py4DSTEM/process/phase/iterative_multislice_ptychography.py +++ b/py4DSTEM/process/phase/iterative_multislice_ptychography.py @@ -974,7 +974,7 @@ def _gradient_descent_adjoint( ) # back-transmit - exit_waves *= xp.conj(obj) / xp.abs(obj) ** 2 + exit_waves *= xp.conj(obj) #/ xp.abs(obj) ** 2 if s > 0: # back-propagate @@ -1076,7 +1076,7 @@ def _projection_sets_adjoint( ) # back-transmit - exit_waves_copy *= xp.conj(obj) / xp.abs(obj) ** 2 + exit_waves_copy *= xp.conj(obj) # / xp.abs(obj) ** 2 if s > 0: # back-propagate @@ -3067,4 +3067,4 @@ def _return_object_fft( obj = np.angle(obj) obj = self._crop_rotate_object_fov(np.sum(obj, axis=0)) - return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) + return np.abs(np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(obj)))) \ No newline at end of file From 387a581a6afc9a93462e50611d4c5501a77ea6e5 Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:43:36 -0700 Subject: [PATCH 354/362] datacube --- py4DSTEM/datacube/datacube.py | 61 ++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/py4DSTEM/datacube/datacube.py b/py4DSTEM/datacube/datacube.py index 159d822ea..ae3a82a36 100644 --- a/py4DSTEM/datacube/datacube.py +++ b/py4DSTEM/datacube/datacube.py @@ -3,7 +3,7 @@ import numpy as np from scipy.interpolate import interp1d from scipy.ndimage import (binary_opening, binary_dilation, - distance_transform_edt, binary_fill_holes, gaussian_filter1d) + distance_transform_edt, binary_fill_holes, gaussian_filter1d, gaussian_filter) from typing import Optional,Union from emdfile import Array, Metadata, Node, Root, tqdmnd @@ -1030,8 +1030,11 @@ def find_Bragg_disks( def get_beamstop_mask( self, threshold = 0.25, - distance_edge = 4.0, + distance_edge = 2.0, include_edges = True, + sigma = 0, + use_max_dp = False, + scale_radial = None, name = "mask_beamstop", returncalc = True, ): @@ -1046,6 +1049,12 @@ def get_beamstop_mask( distance_edge (float): How many pixels to expand the mask. include_edges (bool): If set to True, edge pixels will be included in the mask. + sigma (float): + Gaussain blur std to apply to image before thresholding. + use_max_dp (bool): + Use the max DP instead of the mean DP. + scale_radial (float): + Scale from center of image by this factor (can help with edge) name (string): Name of the output array. returncalc (bool): Set to true to return the result. @@ -1054,19 +1063,42 @@ def get_beamstop_mask( """ - # Calculate dp_mean if needed - if not "dp_mean" in self._branch.keys(): - self.get_dp_mean(); - - # normalized dp_mean - int_sort = np.sort(self.tree("dp_mean").data.ravel()) + if scale_radial is not None: + x = np.arange(self.data.shape[2]) * 2.0 / self.data.shape[2] + y = np.arange(self.data.shape[3]) * 2.0 / self.data.shape[3] + ya, xa = np.meshgrid(y - np.mean(y), x - np.mean(x)) + im_scale = 1.0 + np.sqrt(xa**2 + ya**2)*scale_radial + + # Get image for beamstop mask + if use_max_dp: + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_max(); + # im = self.tree["dp_max"].data.astype('float') + if not "dp_max" in self._branch.keys(): + self.get_dp_max(); + im = self.tree("dp_max").data.copy().astype('float') + else: + if not "dp_mean" in self._branch.keys(): + self.get_dp_mean(); + im = self.tree("dp_mean").data.copy() + + # if not "dp_mean" in self.tree.keys(): + # self.get_dp_mean(); + # im = self.tree["dp_mean"].data.astype('float') + + # smooth and scale if needed + if sigma > 0.0: + im = gaussian_filter(im, sigma, mode='nearest') + if scale_radial is not None: + im *= im_scale + + # Calculate beamstop mask + int_sort = np.sort(im.ravel()) ind = np.round(np.clip( int_sort.shape[0]*threshold, 0,int_sort.shape[0])).astype('int') intensity_threshold = int_sort[ind] - - # Use threshold to calculate initial mask - mask_beamstop = self.tree("dp_mean").data >= intensity_threshold + mask_beamstop = im >= intensity_threshold # clean up mask mask_beamstop = np.logical_not(binary_fill_holes(np.logical_not(mask_beamstop))) @@ -1103,7 +1135,7 @@ def get_beamstop_mask( ) # Add to tree - self.attach( mask_beamstop ) + self.tree(x) # return if returncalc: @@ -1441,7 +1473,4 @@ def get_braggmask( for idx in range(len(vects.data)): qr = np.hypot(self.qxx_raw-vects.qx[idx], self.qyy_raw-vects.qy[idx]) mask = np.logical_and(mask, qr>radius) - return mask - - - + return mask \ No newline at end of file From 5014f0bb7c02291605c42266b4d53f6717a97517 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 18 Jul 2023 12:43:59 -0400 Subject: [PATCH 355/362] attempt to resolve dev/strain conflicts --- py4DSTEM/process/calibration/origin.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/py4DSTEM/process/calibration/origin.py b/py4DSTEM/process/calibration/origin.py index 0b27f5a85..19d2f0c55 100644 --- a/py4DSTEM/process/calibration/origin.py +++ b/py4DSTEM/process/calibration/origin.py @@ -73,11 +73,12 @@ def fit_origin( ): """ Fits the position of the origin of diffraction space to a plane or parabola, - given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, optionally - masked by the Boolean array `mask`. The 2D data arrays may be passed directly as - a 2-tuple to the arg `data`, or, if `data` is either a DataCube or Calibration - instance, they will be retreived automatically. If a DataCube or Calibration are - passed, fitted origin and residuals are stored there directly. + given some 2D arrays (qx0_meas,qy0_meas) of measured center positions, + optionally masked by the Boolean array `mask`. The 2D data arrays may be + passed directly as a 2-tuple to the arg `data`, or, if `data` is either a + DataCube or Calibration instance, they will be retreived automatically. If a + DataCube or Calibration are passed, fitted origin and residuals are stored + there directly. Args: data (2-tuple of 2d arrays): the measured origin position (qx0,qy0) @@ -133,14 +134,14 @@ def fit_origin( # Fit data if mask is None: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, robust_steps=robust_steps, robust_thresh=robust_thresh, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, @@ -149,7 +150,7 @@ def fit_origin( ) else: - popt_x, pcov_x, qx0_fit = fit_2D( + popt_x, pcov_x, qx0_fit, _ = fit_2D( f, qx0_meas, robust=robust, @@ -157,7 +158,7 @@ def fit_origin( robust_thresh=robust_thresh, data_mask=mask == True, ) - popt_y, pcov_y, qy0_fit = fit_2D( + popt_y, pcov_y, qy0_fit, _ = fit_2D( f, qy0_meas, robust=robust, @@ -358,4 +359,3 @@ def get_origin_beamstop(datacube: DataCube, mask: np.ndarray, **kwargs): return qx0, qy0 - From 3c2229adeaf1d568ada57eb531dd1de00fb45488 Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Tue, 18 Jul 2023 12:46:09 -0400 Subject: [PATCH 356/362] attempt to resolve dev/strain conflicts --- py4DSTEM/data/calibration.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/py4DSTEM/data/calibration.py b/py4DSTEM/data/calibration.py index 48acd503e..50ec8f6f9 100644 --- a/py4DSTEM/data/calibration.py +++ b/py4DSTEM/data/calibration.py @@ -64,8 +64,8 @@ class Calibration(Metadata): theta, * p_ellipse, * ellipse, * - QR_rotation_degrees, - QR_flip, + QR_rotation_degrees, * + QR_flip, * QR_rotflip, * probe_semiangle, probe_param, @@ -598,11 +598,13 @@ def ellipse(self,x): # Q/R-space rotation and flip + @call_calibrate def set_QR_rotation_degrees(self,x): self._params['QR_rotation_degrees'] = x def get_QR_rotation_degrees(self): return self._get_value('QR_rotation_degrees') + @call_calibrate def set_QR_flip(self,x): self._params['QR_flip'] = x def get_QR_flip(self): From adc0c9bea50b57ba720094c3e8f41e06b802b3da Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:47:47 -0700 Subject: [PATCH 357/362] bragg vectors --- py4DSTEM/braggvectors/braggvectors.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvectors.py b/py4DSTEM/braggvectors/braggvectors.py index 0f62d9501..f1ff406d0 100644 --- a/py4DSTEM/braggvectors/braggvectors.py +++ b/py4DSTEM/braggvectors/braggvectors.py @@ -236,9 +236,16 @@ def setcal( "rotate" : rotate, } if self.verbose: - print('current calstate: ', self.calstate) + print('current calibration state: ', self.calstate) pass + def calibrate(self): + """ + Autoupdate the calstate when relevant calibrations are set + """ + self.setcal() + + # vector getter method @@ -250,7 +257,7 @@ def get_vectors( ellipse, pixel, rotate - ): + ): """ Returns the bragg vectors at the specified scan position with the specified calibration state. @@ -268,6 +275,7 @@ def get_vectors( ------- vectors : BVects """ + ans = self._v_uncal[scan_x,scan_y].data ans = self.cal._transform( data = ans, @@ -282,7 +290,6 @@ def get_vectors( # copy - def copy(self, name=None): name = name if name is not None else self.name+"_copy" braggvector_copy = BraggVectors( @@ -526,6 +533,4 @@ def _transform( # return - return ans - - + return ans \ No newline at end of file From cf2ea5a8a8876fe33eb920d2fe8292b3a3ff2cfa Mon Sep 17 00:00:00 2001 From: Stephanie Ribet Date: Tue, 18 Jul 2023 09:52:39 -0700 Subject: [PATCH 358/362] bragg vectors methods --- py4DSTEM/braggvectors/braggvector_methods.py | 243 ++++--------------- 1 file changed, 42 insertions(+), 201 deletions(-) diff --git a/py4DSTEM/braggvectors/braggvector_methods.py b/py4DSTEM/braggvectors/braggvector_methods.py index 009f5a193..be766ad49 100644 --- a/py4DSTEM/braggvectors/braggvector_methods.py +++ b/py4DSTEM/braggvectors/braggvector_methods.py @@ -186,7 +186,11 @@ def get_virtual_image( mode = None, geometry = None, name = 'bragg_virtual_image', - returncalc = True + returncalc = True, + center = True, + ellipse = True, + pixel = True, + rotate = True, ): ''' Calculates a virtual image based on the values of the Braggvectors @@ -204,13 +208,22 @@ def get_virtual_image( - 'circle', 'circular': nested 2-tuple, ((qx,qy),radius) - 'annular' or 'annulus': nested 2-tuple, ((qx,qy),(radius_i,radius_o)) - All values are in pixels. Note that (qx,qy) can be skipped, which - assumes peaks centered at (0,0) + Values can be in pixels or calibrated units. Note that (qx,qy) + can be skipped, which assumes peaks centered at (0,0). + center: bool + Apply calibration - center coordinate. + ellipse: bool + Apply calibration - elliptical correction. + pixel: bool + Apply calibration - pixel size. + rotate: bool + Apply calibration - QR rotation. Returns ------- virtual_im : VirtualImage ''' + # parse inputs circle_modes = ['circular','circle'] annulus_modes = ['annular','annulus'] @@ -220,13 +233,13 @@ def get_virtual_image( # set geometry if mode is None: if geometry is None: - center = None + qxy_center = None radial_range = np.array((0,np.inf)) else: if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) if isinstance(geometry[1], int) or isinstance(geometry[1], float): radial_range = np.array((0,geometry[1])) elif len(geometry[1]) == 0: @@ -236,30 +249,44 @@ def get_virtual_image( elif mode == 'circular' or mode == 'circle': radial_range = np.array((0,geometry[1])) if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) elif mode == 'annular' or mode == 'annulus': radial_range = np.array(geometry[1]) if len(geometry[0]) == 0: - center = None + qxy_center = None else: - center = np.array(geometry[0]) + qxy_center = np.array(geometry[0]) # allocate space im_virtual = np.zeros(self.shape) # generate image - for rx,ry in tqdmnd(self.shape[0],self.shape[1]): - p = self.raw[rx,ry] + for rx,ry in tqdmnd( + self.shape[0], + self.shape[1], + ): + # Get user-specified Bragg vectors + p = self.get_vectors( + rx, + ry, + center = center, + ellipse = ellipse, + pixel = pixel, + rotate = rotate, + ) + if p.data.shape[0] > 0: if radial_range is None: im_virtual[rx,ry] = np.sum(p.I) else: - if center is None: + if qxy_center is None: qr = np.hypot(p.qx,p.qy) else: - qr = np.hypot(p.qx - center[0],p.qy - center[1]) + qr = np.hypot( + p.qx - qxy_center[0], + p.qy - qxy_center[1]) sub = np.logical_and( qr >= radial_range[0], qr < radial_range[1]) @@ -284,7 +311,7 @@ def get_virtual_image( } ) # attach to the tree - self.attach( ans) + self.attach(ans) # return if returncalc: @@ -634,192 +661,6 @@ def fit_p_ellipse( if returncalc: return p_ellipse - - # Deprecated?? - - # def index_bragg_directions( - # self, - # x0 = None, - # y0 = None, - # plot = True, - # bvm_vis_params = {}, - # returncalc = False, - # ): - # """ - # From an origin (x0,y0), a set of reciprocal lattice vectors gx,gy, and an pair of - # lattice vectors g1=(g1x,g1y), g2=(g2x,g2y), find the indices (h,k) of all the - # reciprocal lattice directions. - - # Args: - # x0 (float): x-coord of origin - # y0 (float): y-coord of origin - # Plot (bool): plot results - # """ - - # if x0 is None: - # x0 = self.Qshape[0]/2 - # if y0 is None: - # y0 = self.Qshape[0]/2 - - # from py4DSTEM.process.latticevectors import index_bragg_directions - # _, _, braggdirections = index_bragg_directions( - # x0, - # y0, - # self.g['x'], - # self.g['y'], - # self.g1, - # self.g2 - # ) - - # self.braggdirections = braggdirections - - # if plot: - # from py4DSTEM.visualize import show_bragg_indexing - # show_bragg_indexing( - # self.bvm_centered, - # **bvm_vis_params, - # braggdirections = braggdirections, - # points = True - # ) - - # if returncalc: - # return braggdirections - - - - # def add_indices_to_braggvectors( - # self, - # maxPeakSpacing, - # mask = None, - # returncalc = False, - # ): - # """ - # Using the peak positions (qx,qy) and indices (h,k) in the PointList lattice, - # identify the indices for each peak in the PointListArray braggpeaks. - # Return a new braggpeaks_indexed PointListArray, containing a copy of braggpeaks plus - # three additional data columns -- 'h','k', and 'index_mask' -- specifying the peak - # indices with the ints (h,k) and indicating whether the peak was successfully indexed - # or not with the bool index_mask. If `mask` is specified, only the locations where - # mask is True are indexed. - - # Args: - # maxPeakSpacing (float): Maximum distance from the ideal lattice points - # to include a peak for indexing - # qx_shift,qy_shift (number): the shift of the origin in the `lattice` PointList - # relative to the `braggpeaks` PointListArray - # mask (bool): Boolean mask, same shape as the pointlistarray, indicating which - # locations should be indexed. This can be used to index different regions of - # the scan with different lattices - # """ - # from py4DSTEM.process.latticevectors import add_indices_to_braggvectors - - # bragg_peaks_indexed = add_indices_to_braggvectors( - # self.vectors, - # self.braggdirections, - # maxPeakSpacing = maxPeakSpacing, - # qx_shift = self.Qshape[0]/2, - # qy_shift = self.Qshape[1]/2, - # ) - - # self.bragg_peaks_indexed = bragg_peaks_indexed - - # if returncalc: - # return bragg_peaks_indexed - - - # def fit_lattice_vectors_all_DPs(self, returncalc = False): - # """ - # Fits lattice vectors g1,g2 to each diffraction pattern in braggpeaks, given some - # known (h,k) indexing. - - - # """ - - # from py4DSTEM.process.latticevectors import fit_lattice_vectors_all_DPs - # g1g2_map = fit_lattice_vectors_all_DPs(self.bragg_peaks_indexed) - # self.g1g2_map = g1g2_map - # if returncalc: - # return g1g2_map - - # def get_strain_from_reference_region(self, mask, returncalc = False): - # """ - # Gets a strain map from the reference region of real space specified by mask and the - # lattice vector map g1g2_map. - - # Args: - # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - # wherever mask==True - - # """ - # from py4DSTEM.process.latticevectors import get_strain_from_reference_region - - # strainmap_median_g1g2 = get_strain_from_reference_region( - # self.g1g2_map, - # mask = mask, - # ) - - # self.strainmap_median_g1g2 = strainmap_median_g1g2 - - # if returncalc: - # return strainmap_median_g1g2 - - - # def get_strain_from_reference_g1g2(self, mask, returncalc = False): - # """ - # Gets a strain map from the reference lattice vectors g1,g2 and lattice vector map - # g1g2_map. - - - # Args: - # mask (ndarray of bools): use lattice vectors from g1g2_map scan positions - # wherever mask==True - - # """ - # from py4DSTEM.process.latticevectors import get_reference_g1g2 - # g1_ref,g2_ref = get_reference_g1g2(self.g1g2_map, mask) - - # from py4DSTEM.process.latticevectors import get_strain_from_reference_g1g2 - # strainmap_reference_g1g2 = get_strain_from_reference_g1g2(self.g1g2_map, g1_ref, g2_ref) - - # self.strainmap_reference_g1g2 = strainmap_reference_g1g2 - - # if returncalc: - # return strainmap_reference_g1g2 - - # def get_rotated_strain_map(self, mode, g_reference = None, returncalc = True, flip_theta = False): - # """ - # Starting from a strain map defined with respect to the xy coordinate system of - # diffraction space, i.e. where exx and eyy are the compression/tension along the Qx - # and Qy directions, respectively, get a strain map defined with respect to some other - # right-handed coordinate system, in which the x-axis is oriented along (xaxis_x, - # xaxis_y). - - # Args: - # g_referencce (tupe): reference coordinate system for xaxis_x and xaxis_y - # """ - - # assert mode in ("median","reference") - # if g_reference is None: - # g_reference = np.subtract(self.g1, self.g2) - - # from py4DSTEM.process.latticevectors import get_rotated_strain_map - - # if mode == "median": - # strainmap_raw = self.strainmap_median_g1g2 - # elif mode == "reference": - # strainmap_raw = self.strainmap_reference_g1g2 - - # strainmap = get_rotated_strain_map( - # strainmap_raw, - # xaxis_x = g_reference[0], - # xaxis_y = g_reference[1], - # flip_theta = flip_theta - # ) - - # if returncalc: - # return strainmap - - def mask_in_Q( self, mask, From 88adba34957b9afabdbb32112f5aa3c8f135463f Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 18 Jul 2023 14:40:13 -0700 Subject: [PATCH 359/362] Slight changes to fitting, plotting --- py4DSTEM/Untitled.ipynb | 6 +++++ py4DSTEM/process/diffraction/flowlines.py | 22 ++++++++++++++-- py4DSTEM/process/polar/polar_fits.py | 31 +++++++++++++++++------ py4DSTEM/process/polar/polar_peaks.py | 2 ++ 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 py4DSTEM/Untitled.ipynb diff --git a/py4DSTEM/Untitled.ipynb b/py4DSTEM/Untitled.ipynb new file mode 100644 index 000000000..363fcab7e --- /dev/null +++ b/py4DSTEM/Untitled.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/py4DSTEM/process/diffraction/flowlines.py b/py4DSTEM/process/diffraction/flowlines.py index a483740ff..cf84f69f5 100644 --- a/py4DSTEM/process/diffraction/flowlines.py +++ b/py4DSTEM/process/diffraction/flowlines.py @@ -519,6 +519,7 @@ def make_flowline_rainbow_image( power_scaling = 1.0, sum_radial_bins = False, plot_images = True, + figsize = None, ): """ Generate RGB output images from the flowline arrays. @@ -535,6 +536,7 @@ def make_flowline_rainbow_image( power_scaling (float): Power law scaling for flowline intensity output. sum_radial_bins (bool): Sum all radial bins (alternative is to output separate images). plot_images (bool): Plot the outputs for quick visualization. + figsize (2-tuple): Size of output figure. Returns: im_flowline (array): 3D or 4D array containing flowline images @@ -613,7 +615,14 @@ def make_flowline_rainbow_image( im_flowline = np.min(im_flowline,axis=0)[None,:,:,:] if plot_images is True: - fig,ax = plt.subplots(im_flowline.shape[0],1,figsize=(10,im_flowline.shape[0]*10)) + if figsize is None: + fig,ax = plt.subplots( + im_flowline.shape[0],1, + figsize=(10,im_flowline.shape[0]*10)) + else: + fig,ax = plt.subplots( + im_flowline.shape[0],1, + figsize=figsize) if im_flowline.shape[0] > 1: for a0 in range(im_flowline.shape[0]): @@ -729,6 +738,7 @@ def make_flowline_combined_image( power_scaling = 1.0, sum_radial_bins = True, plot_images = True, + figsize = None, ): """ Generate RGB output images from the flowline arrays. @@ -742,6 +752,7 @@ def make_flowline_combined_image( power_scaling (float): Power law scaling for flowline intensities. sum_radial_bins (bool): Sum outputs over radial bins. plot_images (bool): Plot the output images for quick visualization. + figsize (2-tuple): Size of output figure. Returns: im_flowline (array): flowline images @@ -787,7 +798,14 @@ def make_flowline_combined_image( if plot_images is True: - fig,ax = plt.subplots(im_flowline.shape[0],1,figsize=(10,im_flowline.shape[0]*10)) + if figsize is None: + fig,ax = plt.subplots( + im_flowline.shape[0],1, + figsize=(10,im_flowline.shape[0]*10)) + else: + fig,ax = plt.subplots( + im_flowline.shape[0],1, + figsize=figsize) if im_flowline.shape[0] > 1: for a0 in range(im_flowline.shape[0]): diff --git a/py4DSTEM/process/polar/polar_fits.py b/py4DSTEM/process/polar/polar_fits.py index b92b2b7ba..e231dda07 100644 --- a/py4DSTEM/process/polar/polar_fits.py +++ b/py4DSTEM/process/polar/polar_fits.py @@ -12,6 +12,7 @@ def fit_amorphous_ring( coefs = None, mask_dp = None, show_fit_mask = False, + maxfev = None, verbose = False, plot_result = True, plot_log_scale = False, @@ -39,6 +40,8 @@ def fit_amorphous_ring( Dark field mask for fitting, in addition to the radial range specified above. show_fit_mask: bool Set to true to preview the fitting mask and initial guess for the ellipse params + maxfev: int + Max number of fitting evaluations for curve_fit. verbose: bool Print fit results plot_result: bool @@ -159,14 +162,26 @@ def fit_amorphous_ring( else: # Perform elliptic fitting int_mean = np.mean(vals) - coefs = curve_fit( - amorphous_model, - basis, - vals / int_mean, - p0=coefs, - xtol = 1e-12, - bounds = (lb,ub), - )[0] + + if maxfev is None: + coefs = curve_fit( + amorphous_model, + basis, + vals / int_mean, + p0=coefs, + xtol = 1e-8, + bounds = (lb,ub), + )[0] + else: + coefs = curve_fit( + amorphous_model, + basis, + vals / int_mean, + p0=coefs, + xtol = 1e-8, + bounds = (lb,ub), + maxfev = maxfev, + )[0] coefs[4] = np.mod(coefs[4],2*np.pi) coefs[5:8] *= int_mean # bounds=bounds diff --git a/py4DSTEM/process/polar/polar_peaks.py b/py4DSTEM/process/polar/polar_peaks.py index b05434233..6a6e0860a 100644 --- a/py4DSTEM/process/polar/polar_peaks.py +++ b/py4DSTEM/process/polar/polar_peaks.py @@ -717,6 +717,7 @@ def model_radial_background( ring_int = None, refine_model = True, plot_result = True, + figsize = (8,4), ): """ User provided radial background model, of the form: @@ -818,6 +819,7 @@ def background_model(q, *coefs): self.plot_radial_background( q_pixel_units = False, plot_background_model = True, + figsize = figsize, ) From 8e57e1c2c2abdccb28f1b8689fd20356ef5306ab Mon Sep 17 00:00:00 2001 From: Colin Ophus Date: Tue, 18 Jul 2023 15:17:25 -0700 Subject: [PATCH 360/362] Delete Untitled.ipynb --- py4DSTEM/Untitled.ipynb | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 py4DSTEM/Untitled.ipynb diff --git a/py4DSTEM/Untitled.ipynb b/py4DSTEM/Untitled.ipynb deleted file mode 100644 index 363fcab7e..000000000 --- a/py4DSTEM/Untitled.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 5 -} From 41ee4cf9454476fdcbde36ff48c422836505651c Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 19 Jul 2023 13:54:41 -0400 Subject: [PATCH 361/362] update get_cmap deprecations --- py4DSTEM/process/rdf/amorph.py | 2 +- py4DSTEM/process/utils/utils.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/py4DSTEM/process/rdf/amorph.py b/py4DSTEM/process/rdf/amorph.py index 9c80a2807..a537896b9 100644 --- a/py4DSTEM/process/rdf/amorph.py +++ b/py4DSTEM/process/rdf/amorph.py @@ -111,7 +111,7 @@ def plot_strains(strains, cmap="RdBu_r", vmin=None, vmax=None, mask=None): cmap, vmin, vmax: imshow parameters mask: real space mask of values not to show (black) """ - cmap = matplotlib.cm.get_cmap(cmap) + cmap = plt.get_cmap(cmap) if vmin is None: vmin = np.min(strains) if vmax is None: diff --git a/py4DSTEM/process/utils/utils.py b/py4DSTEM/process/utils/utils.py index 1df4e78c5..86257b4dc 100644 --- a/py4DSTEM/process/utils/utils.py +++ b/py4DSTEM/process/utils/utils.py @@ -59,7 +59,7 @@ def radial_reduction( def plot(img, title='Image', savePath=None, cmap='inferno', show=True, vmax=None, figsize=(10, 10), scale=None): fig, ax = plt.subplots(figsize=figsize) - im = ax.imshow(img, interpolation='nearest', cmap=plt.cm.get_cmap(cmap), vmax=vmax) + im = ax.imshow(img, interpolation='nearest', cmap=plt.get_cmap(cmap), vmax=vmax) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(im, cax=cax) @@ -636,7 +636,7 @@ def fourier_resample( #def plot(img, title='Image', savePath=None, cmap='inferno', show=True, vmax=None, # figsize=(10, 10), scale=None): # fig, ax = plt.subplots(figsize=figsize) -# im = ax.imshow(img, interpolation='nearest', cmap=plt.cm.get_cmap(cmap), vmax=vmax) +# im = ax.imshow(img, interpolation='nearest', cmap=plt.get_cmap(cmap), vmax=vmax) # divider = make_axes_locatable(ax) # cax = divider.append_axes("right", size="5%", pad=0.05) # plt.colorbar(im, cax=cax) From e00bab45a9c499585b968b8f276cc3eb7fe0356f Mon Sep 17 00:00:00 2001 From: bsavitzky Date: Wed, 19 Jul 2023 18:25:51 -0400 Subject: [PATCH 362/362] Update version.py to 0.14.3 --- py4DSTEM/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py4DSTEM/version.py b/py4DSTEM/version.py index 4009e43c9..9df5075b8 100644 --- a/py4DSTEM/version.py +++ b/py4DSTEM/version.py @@ -1,2 +1,2 @@ -__version__='0.14.2' +__version__='0.14.3'

      Zu8=_Q#)ptC>tuM2Zf6_{ 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%0DB_ZM6eKwp(8S^WPR)w({k_OmwCrBQ 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 z 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