Source code for magnopy.io._k_resolved

# ================================== LICENSE ===================================
# Magnopy - Python package for magnons.
# Copyright (C) 2023-2025 Magnopy Team
#
# e-mail: anry@uv.es, web: magnopy.org
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# ================================ END LICENSE =================================


from typing import Iterable
import warnings

try:
    import matplotlib.pyplot as plt

    MATPLOTLIB_AVAILABLE = True
    MATPLOTLIB_ERROR_MESSAGE = "If you see this message, please contact developers of the code (see magnopy.org)."
except ImportError:
    MATPLOTLIB_AVAILABLE = False
    MATPLOTLIB_ERROR_MESSAGE = "\n".join(
        [
            "Installation of matplotlib is not found, can not produce .png files",
            "Please install matplotlib with",
            "",
            "    pip install matplotlib",
            "",
        ]
    )
import numpy as np

# Save local scope at this moment
old_dir = set(dir())
old_dir.add("old_dir")


[docs] def output_k_resolved( data, data_headers=None, output_filename=None, kpoints=None, relative=False, rcell=None, flat_indices=None, digits=4, scientific_notation=True, ): r""" .. deprecated:: 0.2.0 Always meant to be a temporary solution. This function will be removed in March of 2026 Outputs any k-resolved data. Parameters ---------- data : (N, M) |array-like|_ Some k-resolved data. N (:math:`\ge 1`) is the amount of kpoints. M is the number of data modes/entries. data_headers : (N, ) list of str, optional Header for the data columns. ``[f"data {i+1} for i in range(len(data))]`` by default. output_filename : str, optional Name of the file for saving the data. If ``None``, then return a list of lines. kpoints : (N, 3) |array-like|_, optional List of the kpoints. ``kpoints[i]`` correspond to the ``data[i]``. relative : bool, default False If ``relative == True``, then given ``kpoints`` are interpreted as relative to the reciprocal unit cell. Otherwise they are interpreted as absolute coordinates. rcell : (3, 3) |array-like|_, optional Reciprocal unit cell. Rows are interpreted as vectors, columns as Cartesian coordinates. flat_indices : (N, 3) |array-like|_, optional kpoints converted to the list of floats according to some rule. Typically used for plotting the band structure. If ``None`` provided, then computed automatically, based on the distance of the given ``kpoints`` (whether absolute or relative). digits : int, default 4 Number of digits after the comma for the data elements. scientific_notation : bool, default True Whether to use scientific notation for the data elements. Returns ------- lines : str Only returned if ``output_filename is None``. Use ``print("\n".join(lines))`` to output the results to the standard output stream. """ warnings.warn( "This function was deprecated in the release v0.2.0. This function will be removed from magnopy in March of 2026" ) # Prepare format for the data elements chars = digits + 1 + 1 + 3 if scientific_notation: chars += 1 + 1 + 3 chars = max(chars, 8) # Format string for data elements if scientific_notation: fmt = f">{chars}.{digits}e" else: fmt = f">{chars}.{digits}f" # Format string for kpoints kp_fmt = ">12.8f" # Prepare the header header = ["#"] if flat_indices is not None or kpoints is not None: header.append(f"{'flat index':>12}") header = header + [f"{tmp:>{chars}}" for tmp in data_headers] if kpoints is not None: if rcell is not None: header.append( " ".join([f"{f'k_{comp}':>12}" for comp in ["b1", "b2", "b3"]]) ) header.append(" ".join([f"{f'k_{comp}':>12}" for comp in "xyz"])) elif relative: header.append( " ".join([f"{f'k_{comp}':>12}" for comp in ["b1", "b2", "b3"]]) ) else: header.append(" ".join([f"{f'k_{comp}':>12}" for comp in "xyz"])) header = " ".join(header) # Output header if output_filename is not None: f = open(output_filename, "w") f.write(header + "\n") else: lines = [header] # Output data for each kpoint for i in range(len(data)): line = [" "] if flat_indices is not None: line.append(f"{flat_indices[i]:{kp_fmt}}") elif kpoints is not None: if i == 0: line.append(f"{0.0:{kp_fmt}}") else: line.append( f"{np.linalg.norm(np.array(kpoints[i], dtype=float) - kpoints[i - 1]):{kp_fmt}}" ) if isinstance(data[i], Iterable): for entry in data[i]: line.append(f"{entry:{fmt}}") else: line.append(f"{data[i]:{fmt}}") if kpoints is not None: if rcell is not None: if relative: k_vec = kpoints[i] @ np.array(rcell) line.append( " ".join([f"{kpoints[i][comp]:{kp_fmt}}" for comp in range(3)]) ) line.append( " ".join([f"{k_vec[comp]:{kp_fmt}}" for comp in range(3)]) ) else: k_vec_rel = kpoints[i] @ np.linalg.inv(rcell) line.append( " ".join([f"{k_vec_rel[comp]:{kp_fmt}}" for comp in range(3)]) ) line.append( " ".join([f"{kpoints[i][comp]:{kp_fmt}}" for comp in range(3)]) ) else: line.append( " ".join([f"{kpoints[i][comp]:{kp_fmt}}" for comp in range(3)]) ) line = " ".join(line) if output_filename is not None: f.write(line + "\n") else: lines.append(line) if output_filename is not None: f.close() else: return lines
[docs] def plot_k_resolved(data, kp=None, output_filename=None, ylabel=None): r""" Plot some k-resolved data. If only the ``data`` are given, then an index of the omegas is used for abscissa (x axis). Parameters ---------- data : (N, M) |array-like|_ Some k-resolved data. N (:math:`\ge 1`) is the amount of kpoints. M is the number of data modes/entries. kp : :py:class:`wulfric.Kpoints`, optional. Instance of the :py:class:`wulfric.Kpoints` class. It should be the same instance that were used in the preparation of the ``data``. output_filename : str, optional Name of the file for saving the image. If ``None``, then the graph would be opened in the interactive matplotlib window. ylabel : str, optional Label for the ordinate (y axis). """ if not MATPLOTLIB_AVAILABLE: import warnings warnings.warn(MATPLOTLIB_ERROR_MESSAGE, RuntimeWarning) return data = np.array(data).T fig, ax = plt.subplots() if len(data.shape) == 2: for entry in data: if kp is not None: ax.plot(kp.flat_points(), entry, lw=1, color="#A47864") else: ax.plot(entry, lw=1, color="#A47864") ax.set_xlim(0, len(entry)) else: if kp is not None: ax.plot(kp.flat_points(), data, lw=1, color="#A47864") else: ax.plot(data, lw=1, color="#A47864") ax.set_xlim(0, len(data)) if kp is not None: ax.set_xticks(kp.ticks(), kp.labels, fontsize=13) ax.set_xlim(kp.ticks()[0], kp.ticks()[-1]) ax.vlines( kp.ticks(), 0, 1, lw=0.5, color="grey", ls="dashed", zorder=0, transform=ax.get_xaxis_transform(), ) if ylabel is not None: ax.set_ylabel(ylabel, fontsize=15) ax.hlines( 0, 0, 1, lw=0.5, color="grey", linestyle="dashed", transform=ax.get_yaxis_transform(), ) if output_filename is not None: plt.savefig(output_filename, dpi=400, bbox_inches="tight") else: plt.show() plt.close()
# Populate __all__ with objects defined in this file __all__ = list(set(dir()) - old_dir) # Remove all semi-private objects __all__ = [i for i in __all__ if not i.startswith("_")] del old_dir