From c0e2bf7c59feeab0ea17b0c3abf8be5e35f5f387 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 10 Aug 2022 14:55:55 +0200 Subject: [PATCH] Implement peak asymmetries for CrysPy P1D --- easyDiffractionLib/Interfaces/cryspy.py | 29 +++++++-- easyDiffractionLib/Interfaces/cryspyV2.py | 29 +++++++-- easyDiffractionLib/Profiles/P1D.py | 36 +++++++++++ easyDiffractionLib/calculators/cryspy.py | 14 +++++ .../elements/Experiments/Experiment.py | 60 +++++++++++++++++-- 5 files changed, 154 insertions(+), 14 deletions(-) diff --git a/easyDiffractionLib/Interfaces/cryspy.py b/easyDiffractionLib/Interfaces/cryspy.py index dbf9fc41..cde56b76 100644 --- a/easyDiffractionLib/Interfaces/cryspy.py +++ b/easyDiffractionLib/Interfaces/cryspy.py @@ -48,12 +48,16 @@ class Cryspy(InterfaceTemplate): "Bani": "b_iso_or_equiv", } _instrument_link = { + "wavelength": "wavelength", "resolution_u": "u", "resolution_v": "v", "resolution_w": "w", "resolution_x": "x", "resolution_y": "y", - "wavelength": "wavelength", + "reflex_asymmetry_p1": "p1", + "reflex_asymmetry_p2": "p2", + "reflex_asymmetry_p3": "p3", + "reflex_asymmetry_p4": "p4" } _polarization_link = { "polarization": "polarization", @@ -106,15 +110,29 @@ def create(self, model): model_key = self.__identify(model) if issubclass(t_, Instrument1DCWParameters): self.calculator.createModel(model_key, "powder1DCW") - # These parameters are linked to the Resolution and Setup cryspy objects + + # These parameters are linked to the Resolution, Peak Asymmetry and Setup cryspy objects res_key = self.calculator.createResolution() + asymm_key = self.calculator.createReflexAsymmetry() setup_key = self.calculator.createSetup() + keys = self._instrument_link.copy() - keys.pop("wavelength") + res_keys = {k: v for k, v in keys.items() if 'resolution' in k} + asymm_keys = {k: v for k, v in keys.items() if 'reflex_asymmetry' in k} + setup_keys = {k: v for k, v in keys.items() if 'wavelength' in k} + r_list.append( ItemContainer( res_key, - keys, + res_keys, + self.calculator.genericReturn, + self.calculator.genericUpdate, + ) + ) + r_list.append( + ItemContainer( + asymm_key, + asymm_keys, self.calculator.genericReturn, self.calculator.genericUpdate, ) @@ -122,11 +140,12 @@ def create(self, model): r_list.append( ItemContainer( setup_key, - {"wavelength": self._instrument_link["wavelength"]}, + setup_keys, self.calculator.genericReturn, self.calculator.genericUpdate, ) ) + if issubclass(t_, Instrument1DTOFParameters): self.calculator.createModel(model_key, "powder1DTOF") # These parameters are linked to the Resolution and Setup cryspy objects diff --git a/easyDiffractionLib/Interfaces/cryspyV2.py b/easyDiffractionLib/Interfaces/cryspyV2.py index 203003a8..b1cb7c5e 100644 --- a/easyDiffractionLib/Interfaces/cryspyV2.py +++ b/easyDiffractionLib/Interfaces/cryspyV2.py @@ -276,12 +276,16 @@ class CW(CW_type): """ _instrument_link = { + "wavelength": "wavelength", "resolution_u": "u", "resolution_v": "v", "resolution_w": "w", "resolution_x": "x", "resolution_y": "y", - "wavelength": "wavelength", + "reflex_asymmetry_p1": "p1", + "reflex_asymmetry_p2": "p2", + "reflex_asymmetry_p3": "p3", + "reflex_asymmetry_p4": "p4" } def create(self, model: B) -> List[ItemContainer]: @@ -292,15 +296,29 @@ def create(self, model: B) -> List[ItemContainer]: # Link the Instrumental parameters to the calculator. if issubclass(t_, Instrument1DCWParameters): self.calculator.createModel(model_key, "powder1DCW") - # These parameters are linked to the Resolution and Setup cryspy objects + + # These parameters are linked to the Resolution, Peak Asymmetry and Setup cryspy objects res_key = self.calculator.createResolution() + asymm_key = self.calculator.createReflexAsymmetry() setup_key = self.calculator.createSetup() + keys = self._instrument_link.copy() - keys.pop("wavelength") + res_keys = {k: v for k, v in keys.items() if 'resolution' in k} + asymm_keys = {k: v for k, v in keys.items() if 'reflex_asymmetry' in k} + setup_keys = {k: v for k, v in keys.items() if 'wavelength' in k} + r_list.append( ItemContainer( res_key, - keys, + res_keys, + self.calculator.genericReturn, + self.calculator.genericUpdate, + ) + ) + r_list.append( + ItemContainer( + asymm_key, + asymm_keys, self.calculator.genericReturn, self.calculator.genericUpdate, ) @@ -308,11 +326,12 @@ def create(self, model: B) -> List[ItemContainer]: r_list.append( ItemContainer( setup_key, - {"wavelength": self._instrument_link["wavelength"]}, + setup_keys, self.calculator.genericReturn, self.calculator.genericUpdate, ) ) + return r_list diff --git a/easyDiffractionLib/Profiles/P1D.py b/easyDiffractionLib/Profiles/P1D.py index 95bac6d7..0d4935de 100644 --- a/easyDiffractionLib/Profiles/P1D.py +++ b/easyDiffractionLib/Profiles/P1D.py @@ -211,6 +211,26 @@ class Instrument1DCWParameters(BaseObj): "value": 0.0, "fixed": True, }, + "reflex_asymmetry_p1": { + "name": "reflex_asymmetry_p1", + "value": 0.0, + "fixed": True, + }, + "reflex_asymmetry_p2": { + "name": "reflex_asymmetry_p2", + "value": 0.0, + "fixed": True, + }, + "reflex_asymmetry_p3": { + "name": "reflex_asymmetry_p3", + "value": 0.0, + "fixed": True, + }, + "reflex_asymmetry_p4": { + "name": "reflex_asymmetry_p4", + "value": 0.0, + "fixed": True, + } } wavelength: ClassVar[Parameter] @@ -219,6 +239,10 @@ class Instrument1DCWParameters(BaseObj): resolution_w: ClassVar[Parameter] resolution_x: ClassVar[Parameter] resolution_y: ClassVar[Parameter] + reflex_asymmetry_p1: ClassVar[Parameter] + reflex_asymmetry_p2: ClassVar[Parameter] + reflex_asymmetry_p3: ClassVar[Parameter] + reflex_asymmetry_p4: ClassVar[Parameter] def __init__( self, @@ -228,6 +252,10 @@ def __init__( resolution_w: Optional[Union[Parameter, float]] = None, resolution_x: Optional[Union[Parameter, float]] = None, resolution_y: Optional[Union[Parameter, float]] = None, + reflex_asymmetry_p1: Optional[Union[Parameter, float]] = None, + reflex_asymmetry_p2: Optional[Union[Parameter, float]] = None, + reflex_asymmetry_p3: Optional[Union[Parameter, float]] = None, + reflex_asymmetry_p4: Optional[Union[Parameter, float]] = None, interface: Optional[iF] = None, ): super(Instrument1DCWParameters, self).__init__( @@ -249,6 +277,14 @@ def __init__( self.resolution_x = resolution_x if resolution_y is not None: self.resolution_y = resolution_y + if reflex_asymmetry_p1 is not None: + self.reflex_asymmetry_p1 = reflex_asymmetry_p1 + if reflex_asymmetry_p2 is not None: + self.reflex_asymmetry_p2 = reflex_asymmetry_p2 + if reflex_asymmetry_p3 is not None: + self.reflex_asymmetry_p3 = reflex_asymmetry_p3 + if reflex_asymmetry_p4 is not None: + self.reflex_asymmetry_p4 = reflex_asymmetry_p4 self.name = self._name self.interface = interface diff --git a/easyDiffractionLib/calculators/cryspy.py b/easyDiffractionLib/calculators/cryspy.py index 4116470f..6fa23dc0 100644 --- a/easyDiffractionLib/calculators/cryspy.py +++ b/easyDiffractionLib/calculators/cryspy.py @@ -25,6 +25,7 @@ def __init__(self): self.conditions = { "wavelength": 1.25, "resolution": {"u": 0.001, "v": 0.001, "w": 0.001, "x": 0.000, "y": 0.000}, + "reflex_asymmetry": {"p1": 0.0, "p2": 0.0, "p3": 0.0, "p4": 0.0} } self.conditions_TOF = { "ttheta_bank": 0, @@ -282,6 +283,19 @@ def updateResolution(self, key: str, **kwargs): for r_key in kwargs.keys(): setattr(resolution, r_key, kwargs[key]) + def createReflexAsymmetry(self) -> str: + key = "pd_instr_reflex_asymmetry" + reflex_asymmetry = cryspy.PdInstrReflexAsymmetry(**self.conditions["reflex_asymmetry"]) + self.storage[key] = reflex_asymmetry + if self.model is not None: + setattr(self.model, key, reflex_asymmetry) + return key + + def updateReflexAsymmetry(self, key: str, **kwargs): + reflex_asymmetry = self.storage[key] + for r_key in kwargs.keys(): + setattr(reflex_asymmetry, r_key, kwargs[key]) + def powder_1d_calculate( self, x_array: np.ndarray, full_return: bool = False, **kwargs ): diff --git a/easyDiffractionLib/elements/Experiments/Experiment.py b/easyDiffractionLib/elements/Experiments/Experiment.py index 453ae3b0..89daad96 100644 --- a/easyDiffractionLib/elements/Experiments/Experiment.py +++ b/easyDiffractionLib/elements/Experiments/Experiment.py @@ -56,6 +56,34 @@ class Pars1D(BaseObj): 'name': 'resolution_y', 'value': 0.0, 'fixed': True + }, + 'reflex_asymmetry_p1': { + '@module': 'easyCore.Objects.Base', + '@class': 'Parameter', + 'name': 'reflex_asymmetry_p1', + 'value': 0.0, + 'fixed': True + }, + 'reflex_asymmetry_p2': { + '@module': 'easyCore.Objects.Base', + '@class': 'Parameter', + 'name': 'reflex_asymmetry_p2', + 'value': 0.0, + 'fixed': True + }, + 'reflex_asymmetry_p3': { + '@module': 'easyCore.Objects.Base', + '@class': 'Parameter', + 'name': 'reflex_asymmetry_p3', + 'value': 0.0, + 'fixed': True + }, + 'reflex_asymmetry_p4': { + '@module': 'easyCore.Objects.Base', + '@class': 'Parameter', + 'name': 'reflex_asymmetry_p4', + 'value': 0.0, + 'fixed': True } } @@ -63,11 +91,15 @@ def __init__(self, wavelength: Parameter, resolution_u: Parameter, resolution_v: Parameter, resolution_w: Parameter, resolution_x: Parameter, resolution_y: Parameter, + reflex_asymmetry_p1: Parameter, reflex_asymmetry_p2: Parameter, + reflex_asymmetry_p3: Parameter, reflex_asymmetry_p4: Parameter, interface=None): super().__init__(self.__class__.__name__, wavelength=wavelength, resolution_u=resolution_u, resolution_v=resolution_v, resolution_w=resolution_w, - resolution_x=resolution_x, resolution_y=resolution_y) + resolution_x=resolution_x, resolution_y=resolution_y, + reflex_asymmetry_p1=reflex_asymmetry_p1, reflex_asymmetry_p2=reflex_asymmetry_p2, + reflex_asymmetry_p3=reflex_asymmetry_p3, reflex_asymmetry_p4=reflex_asymmetry_p4) self.name = self._name self.interface = interface @@ -78,7 +110,11 @@ def from_pars(cls, resolution_v: float = _defaults['resolution_v']['value'], resolution_w: float = _defaults['resolution_w']['value'], resolution_x: float = _defaults['resolution_x']['value'], - resolution_y: float = _defaults['resolution_y']['value'] + resolution_y: float = _defaults['resolution_y']['value'], + reflex_asymmetry_p1: float = _defaults['reflex_asymmetry_p1']['value'], + reflex_asymmetry_p2: float = _defaults['reflex_asymmetry_p2']['value'], + reflex_asymmetry_p3: float = _defaults['reflex_asymmetry_p3']['value'], + reflex_asymmetry_p4: float = _defaults['reflex_asymmetry_p4']['value'] ): defaults = deepcopy(cls._defaults) defaults['wavelength']['value'] = wavelength @@ -93,9 +129,19 @@ def from_pars(cls, resolution_x = _decoder.process_decoded(defaults['resolution_x']) defaults['resolution_y']['value'] = resolution_y resolution_y = _decoder.process_decoded(defaults['resolution_y']) + defaults['reflex_asymmetry_p1']['value'] = reflex_asymmetry_p1 + reflex_asymmetry_p1 = _decoder.process_decoded(defaults['reflex_asymmetry_p1']) + defaults['reflex_asymmetry_p2']['value'] = reflex_asymmetry_p2 + reflex_asymmetry_p2 = _decoder.process_decoded(defaults['reflex_asymmetry_p2']) + defaults['reflex_asymmetry_p3']['value'] = reflex_asymmetry_p3 + reflex_asymmetry_p3 = _decoder.process_decoded(defaults['reflex_asymmetry_p3']) + defaults['reflex_asymmetry_p4']['value'] = reflex_asymmetry_p4 + reflex_asymmetry_p4 = _decoder.process_decoded(defaults['reflex_asymmetry_p4']) return cls(wavelength=wavelength, resolution_u=resolution_u, resolution_v=resolution_v, resolution_w=resolution_w, - resolution_x=resolution_x, resolution_y=resolution_y) + resolution_x=resolution_x, resolution_y=resolution_y, + reflex_asymmetry_p1=reflex_asymmetry_p1, reflex_asymmetry_p2=reflex_asymmetry_p2, + reflex_asymmetry_p3=reflex_asymmetry_p3, reflex_asymmetry_p4=reflex_asymmetry_p4) @classmethod def default(cls): @@ -106,6 +152,12 @@ def default(cls): resolution_w = _decoder.process_decoded(defaults['resolution_w']) resolution_x = _decoder.process_decoded(defaults['resolution_x']) resolution_y = _decoder.process_decoded(defaults['resolution_y']) + reflex_asymmetry_p1 = _decoder.process_decoded(defaults['reflex_asymmetry_p1']) + reflex_asymmetry_p2 = _decoder.process_decoded(defaults['reflex_asymmetry_p2']) + reflex_asymmetry_p3 = _decoder.process_decoded(defaults['reflex_asymmetry_p3']) + reflex_asymmetry_p4 = _decoder.process_decoded(defaults['reflex_asymmetry_p4']) return cls(wavelength=wavelength, resolution_u=resolution_u, resolution_v=resolution_v, resolution_w=resolution_w, - resolution_x=resolution_x, resolution_y=resolution_y) + resolution_x=resolution_x, resolution_y=resolution_y, + reflex_asymmetry_p1=reflex_asymmetry_p1, reflex_asymmetry_p2=reflex_asymmetry_p2, + reflex_asymmetry_p3=reflex_asymmetry_p3, reflex_asymmetry_p4=reflex_asymmetry_p4)