From 130daebc977ce25c74c288d57574e8de4fdf2bfc Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Sun, 21 Apr 2024 12:33:13 +0900 Subject: [PATCH] Refactoring: - Remove AnalyzerDetail - change loglevel for "couldn't read the temperature" - Update rebin (to treat the binned coords more correctly) --- src/arpes/_typing.py | 18 ++++-------------- src/arpes/analysis/general.py | 29 +++++++++++++++++++++++++---- src/arpes/endstations/fits_utils.py | 12 +++++++----- src/arpes/plotting/bz.py | 10 ++++------ src/arpes/plotting/utils.py | 18 +++++++----------- src/arpes/xarray_extensions.py | 9 ++++----- tests/test_basic_data_loading.py | 6 +++--- 7 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/arpes/_typing.py b/src/arpes/_typing.py index 9ced008c..6d915606 100644 --- a/src/arpes/_typing.py +++ b/src/arpes/_typing.py @@ -184,6 +184,7 @@ class AnalyzerInfo(TypedDict, total=False): see analyzer_info in xarray_extensions.py (around line# 1490) """ + name: str lens_mode: str | None lens_mode_name: str | None acquisition_mode: str @@ -192,23 +193,13 @@ class AnalyzerInfo(TypedDict, total=False): slit_width: float slit_number: str | int lens_table: None + parallel_deflectors: bool + perpendicular_deflectors: bool analyzer_type: str | None mcp_voltage: float work_function: float # is_slit_vertical: bool - - -class AnalyzerDetail(TypedDict, total=False): - """TypedDict for analyzer_detail. - - Used in analyzer_detail in xarray_extensions.py (around line# 1597) - """ - - name: str - parallel_deflectors: bool - perpendicular_deflectors: bool - type: str radius: str | float @@ -331,7 +322,6 @@ class DAQInfo(TypedDict, total=False): class Spectrometer(AnalyzerInfo, Coordinates, DAQInfo, total=False): - name: str type: str rad_per_pixel: float dof: list[str] @@ -347,7 +337,7 @@ class ExperimentInfo( AnalyzerInfo, total=False, ): - analyzer_detail: AnalyzerDetail + pass class ARPESAttrs(Spectrometer, LightSourceInfo, SampleInfo, total=False): diff --git a/src/arpes/analysis/general.py b/src/arpes/analysis/general.py index e248ffd6..461b5667 100644 --- a/src/arpes/analysis/general.py +++ b/src/arpes/analysis/general.py @@ -2,6 +2,7 @@ from __future__ import annotations +from logging import DEBUG, INFO, Formatter, StreamHandler, getLogger from typing import TYPE_CHECKING, Literal import numpy as np @@ -29,6 +30,18 @@ "fit_fermi_edge", ) +LOGLEVELS = (DEBUG, INFO) +LOGLEVEL = LOGLEVELS[0] +logger = getLogger(__name__) +fmt = "%(asctime)s %(levelname)s %(name)s :%(message)s" +formatter = Formatter(fmt) +handler = StreamHandler() +handler.setLevel(LOGLEVEL) +logger.setLevel(LOGLEVEL) +handler.setFormatter(formatter) +logger.addHandler(handler) +logger.propagate = False + @update_provenance("Fit Fermi Edge") def fit_fermi_edge( @@ -225,14 +238,22 @@ def _bin( method: Literal["sum", "mean"], ) -> DataType: original_left, original_right = ( - data.coords[bin_axis].values[0], - data.coords[bin_axis].values[-1], + data.coords[bin_axis].min().item(), + data.coords[bin_axis].max().item(), ) original_region = original_right - original_left if method == "sum": - data = data.groupby_bins(bin_axis, bins).sum().rename({bin_axis + "_bins": bin_axis}) + data = ( + data.groupby_bins(bin_axis, bins, precision=10) + .sum() + .rename({bin_axis + "_bins": bin_axis}) + ) elif method == "mean": - data = data.groupby_bins(bin_axis, bins).mean().rename({bin_axis + "_bins": bin_axis}) + data = ( + data.groupby_bins(bin_axis, bins, precision=10) + .mean() + .rename({bin_axis + "_bins": bin_axis}) + ) else: msg = "method must be sum or mean" raise TypeError(msg) diff --git a/src/arpes/endstations/fits_utils.py b/src/arpes/endstations/fits_utils.py index f7c11ab9..d10650b5 100644 --- a/src/arpes/endstations/fits_utils.py +++ b/src/arpes/endstations/fits_utils.py @@ -65,8 +65,9 @@ def extract_coords( Returns: A tuple consisting of the coordinate arrays, the dimension names, and their shapes """ - if dimension_renamings is None: - dimension_renamings = DEFAULT_DIMENSION_RENAMINGS + dimension_renamings = ( + dimension_renamings if dimension_renamings else DEFAULT_DIMENSION_RENAMINGS + ) try: n_loops = attrs["LWLVLPN"] @@ -181,7 +182,7 @@ def find_clean_coords( attrs: dict[str, Any], spectra: Any = None, mode: str = "ToF", - dimension_renamings: Any = None, + dimension_renamings: dict[str, str] | None = None, ) -> tuple[CoordsDict, dict[str, list[Dimension]], dict[str, Any]]: """Determines the scan degrees of freedom, and reads coordinates. @@ -211,8 +212,9 @@ def find_clean_coords( A tuple consisting of (coordinates, dimensions, np shape of actual spectrum) """ - if dimension_renamings is None: - dimension_renamings = DEFAULT_DIMENSION_RENAMINGS + dimension_renamings = ( + dimension_renamings if dimension_renamings else DEFAULT_DIMENSION_RENAMINGS + ) scan_coords, scan_dimension, scan_shape = extract_coords( attrs, diff --git a/src/arpes/plotting/bz.py b/src/arpes/plotting/bz.py index bf9639a9..12ae2e31 100644 --- a/src/arpes/plotting/bz.py +++ b/src/arpes/plotting/bz.py @@ -150,7 +150,6 @@ def plot_plane_to_bz( cell: Cell, plane: str | list[NDArray[np.float_]], ax: Axes3D, - special_points: dict[str, NDArray[np.float_]] | None = None, facecolor: ColorType = "red", ) -> None: """Plots a 2D cut plane onto a Brillouin zone. @@ -171,7 +170,6 @@ def plot_plane_to_bz( plane_points: list[NDArray[np.float_]] = process_kpath( plane, cell, - special_points=special_points, )[0] else: plane_points = plane @@ -190,7 +188,7 @@ def plot_data_to_bz( data: xr.DataArray, cell: Cell, **kwargs: Incomplete, -) -> Path | tuple[Figure, Axes]: +) -> Path | tuple[Figure | None, Axes]: """A dimension agnostic tool used to plot ARPES data onto a Brillouin zone.""" if len(data) == TWO_DIMENSION + 1: raise NotImplementedError @@ -210,7 +208,7 @@ def plot_data_to_bz2d( # noqa: PLR0913 *, mask: bool = True, **kwargs: Incomplete, -) -> Path | tuple[Figure, Axes]: +) -> Path | tuple[Figure | None, Axes]: """Plots data onto the 2D Brillouin zone. Args: @@ -269,8 +267,8 @@ def plot_data_to_bz2d( # noqa: PLR0913 cmap.set_bad((1, 1, 1, 0)) - delta_x = np.dot(np.array(bz_number), icell[:2, 0]) - delta_y = np.dot(np.array(bz_number), icell[:2, 1]) + delta_x = np.dot(np.array(bz_number), np.array(icell)[:2, 0]) + delta_y = np.dot(np.array(bz_number), np.array(icell)[:2, 1]) ax.pcolormesh( raveled.data_vars[dims[0]].values + delta_x, diff --git a/src/arpes/plotting/utils.py b/src/arpes/plotting/utils.py index 88f6de6b..ba94f56d 100644 --- a/src/arpes/plotting/utils.py +++ b/src/arpes/plotting/utils.py @@ -861,17 +861,13 @@ def remove_colorbars(fig: Figure | None = None) -> None: # TODO: after colorbar removal, plots should be relaxed/rescaled to occupy space previously # allocated to colorbars for now, can follow this with plt.tight_layout() COLORBAR_ASPECT_RATIO = 20 - try: - if fig is not None: - for ax in fig.axes: - aspect_ragio = ax.get_aspect() - assert isinstance(aspect_ragio, float) - if aspect_ragio >= COLORBAR_ASPECT_RATIO: - ax.remove() - else: - remove_colorbars(plt.gcf()) - except Exception: - logger.exception("Exception occurs") + if fig is not None: + for ax in fig.axes: + aspect_ratio = ax.get_aspect() + if isinstance(aspect_ratio, float) and aspect_ratio >= COLORBAR_ASPECT_RATIO: + ax.remove() + else: + remove_colorbars(plt.gcf()) def calculate_aspect_ratio(data: xr.DataArray) -> float: diff --git a/src/arpes/xarray_extensions.py b/src/arpes/xarray_extensions.py index 2f79f09f..b0f77251 100644 --- a/src/arpes/xarray_extensions.py +++ b/src/arpes/xarray_extensions.py @@ -106,7 +106,6 @@ from ._typing import ( ANGLE, HIGH_SYMMETRY_POINTS, - AnalyzerDetail, AnalyzerInfo, BeamLineSettings, DAQInfo, @@ -144,7 +143,7 @@ UNSPESIFIED = 0.1 LOGLEVELS = (DEBUG, INFO) -LOGLEVEL = LOGLEVELS[0] +LOGLEVEL = LOGLEVELS[1] logger = getLogger(__name__) fmt = "%(asctime)s %(levelname)s %(name)s :%(message)s" formatter = Formatter(fmt) @@ -1588,13 +1587,13 @@ def undulator_info(self) -> dict[str, str | float | None]: } @property - def analyzer_detail(self) -> AnalyzerDetail: + def analyzer_detail(self) -> AnalyzerInfo: """Details about the analyzer, its capabilities, and metadata.""" return { "name": self._obj.attrs.get("analyzer_name", self._obj.attrs.get("analyzer", "")), "parallel_deflectors": self._obj.attrs.get("parallel_deflectors", False), "perpendicular_deflectors": self._obj.attrs.get("perpendicular_deflectors", False), - "type": self._obj.attrs.get("analyzer_type", ""), + "analyzer_type": self._obj.attrs.get("analyzer_type", ""), "radius": self._obj.attrs.get("analyzer_radius", np.nan), } @@ -1622,7 +1621,7 @@ def temp(self) -> float | Literal["RT", "LT"]: if attr in self._obj.attrs: return self._obj.attrs[attr] msg = "Could not read temperature off any standard attr" - warnings.warn(msg, stacklevel=2) + logger.debug(msg, stacklevel=2) return np.nan def generic_fermi_surface(self, fermi_energy: float) -> XrTypes: diff --git a/tests/test_basic_data_loading.py b/tests/test_basic_data_loading.py index cbd6d1f7..25560c72 100644 --- a/tests/test_basic_data_loading.py +++ b/tests/test_basic_data_loading.py @@ -70,7 +70,7 @@ class TestMetadata: "probe": None, "probe_detail": None, "analyzer_detail": { - "type": "hemispherical", + "analyzer_type": "hemispherical", "radius": 150, "name": "Specs PHOIBOS 150", "parallel_deflectors": False, @@ -164,7 +164,7 @@ class TestMetadata: "parallel_deflectors": False, "perpendicular_deflectors": False, "radius": np.nan, - "type": "hemispherical", + "analyzer_type": "hemispherical", }, }, "analyzer_info": { @@ -248,7 +248,7 @@ class TestMetadata: "probe": None, "probe_detail": None, "analyzer_detail": { - "type": "hemispherical", + "analyzer_type": "hemispherical", "radius": np.nan, "name": "Scienta R4000", "parallel_deflectors": False,