|
23 | 23 | LinkedPhasesFactory, |
24 | 24 | ) |
25 | 25 | from easydiffraction.datablocks.experiment.categories.peak.factory import PeakFactory |
| 26 | +from easydiffraction.io.cif.parse import read_cif_str |
26 | 27 | from easydiffraction.io.cif.serialize import experiment_to_cif |
27 | 28 | from easydiffraction.utils.logging import console |
28 | 29 | from easydiffraction.utils.logging import log |
@@ -122,6 +123,22 @@ def show_current_diffrn_type(self) -> None: |
122 | 123 | console.paragraph('Current diffrn type') |
123 | 124 | console.print(self.diffrn_type) |
124 | 125 |
|
| 126 | + def _restore_switchable_types(self, block: object) -> None: |
| 127 | + """ |
| 128 | + Restore switchable category types from a parsed CIF block. |
| 129 | +
|
| 130 | + Called by the factory immediately after the experiment object is |
| 131 | + created and before any category parameters are loaded from CIF. |
| 132 | + Subclasses with switchable categories must override this method |
| 133 | + and call their ``_set_<type>`` private setter for each category |
| 134 | + whose active implementation is identified by a CIF type tag. |
| 135 | +
|
| 136 | + Parameters |
| 137 | + ---------- |
| 138 | + block : object |
| 139 | + Parsed ``gemmi.cif.Block`` to read type tags from. |
| 140 | + """ |
| 141 | + |
125 | 142 | @property |
126 | 143 | def as_cif(self) -> str: |
127 | 144 | """Serialize this experiment to a CIF fragment.""" |
@@ -762,3 +779,47 @@ def show_current_peak_profile_type(self) -> None: |
762 | 779 | """Print the currently selected peak profile type.""" |
763 | 780 | console.paragraph('Current peak profile type') |
764 | 781 | console.print(self.peak_profile_type) |
| 782 | + |
| 783 | + def _set_peak_profile_type(self, new_type: str) -> None: |
| 784 | + """ |
| 785 | + Switch the peak profile type without console output. |
| 786 | +
|
| 787 | + Used internally by the factory when restoring state from CIF so |
| 788 | + that no user-facing warnings or progress messages are emitted. |
| 789 | + Invalid type tags are logged as warnings and ignored. |
| 790 | +
|
| 791 | + Parameters |
| 792 | + ---------- |
| 793 | + new_type : str |
| 794 | + Peak profile type tag (e.g. ``'split pseudo-voigt'``). |
| 795 | + """ |
| 796 | + supported = PeakFactory.supported_for( |
| 797 | + scattering_type=self.type.scattering_type.value, |
| 798 | + beam_mode=self.type.beam_mode.value, |
| 799 | + ) |
| 800 | + supported_tags = [k.type_info.tag for k in supported] |
| 801 | + if new_type not in supported_tags: |
| 802 | + log.warning( |
| 803 | + f"Unsupported peak profile '{new_type}' in CIF. " |
| 804 | + f'Supported: {supported_tags}. Keeping default.', |
| 805 | + ) |
| 806 | + return |
| 807 | + self._peak = PeakFactory.create(new_type) |
| 808 | + self._peak_profile_type = new_type |
| 809 | + |
| 810 | + def _restore_switchable_types(self, block: object) -> None: |
| 811 | + """ |
| 812 | + Restore switchable category types for powder experiments. |
| 813 | +
|
| 814 | + Reads ``_peak.profile_type`` from the CIF block and switches to |
| 815 | + the matching peak implementation before category parameters are |
| 816 | + loaded, ensuring profile-specific descriptors are present. |
| 817 | +
|
| 818 | + Parameters |
| 819 | + ---------- |
| 820 | + block : object |
| 821 | + Parsed ``gemmi.cif.Block`` to read type tags from. |
| 822 | + """ |
| 823 | + peak_type = read_cif_str(block, '_peak.profile_type') |
| 824 | + if peak_type is not None: |
| 825 | + self._set_peak_profile_type(peak_type) |
0 commit comments