Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement web JSON export #318

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions euphonic/cli/dispersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@

from euphonic.plot import plot_1d
from euphonic.styles import base_style
from euphonic.writers.phonon_website import write_phonon_website_json
from euphonic import Spectrum1D, ForceConstants, QpointFrequencies
from .utils import (load_data_from_file, get_args, _bands_from_force_constants,
_compose_style,
_get_q_distance, matplotlib_save_or_show, _get_cli_parser,
_get_title,
_calc_modes_kwargs, _plot_label_kwargs)


def main(params: Optional[List[str]] = None) -> None:
args = get_args(get_parser(), params)

frequencies_only = not args.reorder # Need eigenvectors to reorder
# Need eigenvectors to reorder bands or write website JSON
frequencies_only = args.save_web_json is None and not args.reorder

data = load_data_from_file(args.filename, verbose=True,
frequencies_only=frequencies_only)
if not frequencies_only and type(data) is QpointFrequencies:
Expand All @@ -33,6 +37,12 @@ def main(params: Optional[List[str]] = None) -> None:
split_args = {'btol': args.btol}
x_tick_labels = None

if args.save_web_json is not None:
write_phonon_website_json(modes=bands,
name=_get_title(args.filename, args.title),
output_file=args.save_web_json,
x_tick_labels=x_tick_labels)

bands.frequencies_unit = args.energy_unit

print("Mapping modes to 1D band-structure")
Expand All @@ -54,6 +64,7 @@ def main(params: Optional[List[str]] = None) -> None:

if args.save_json:
spectrum.to_json_file(args.save_json)

with matplotlib.style.context(style):
_ = plot_1d(spectra,
ymin=args.e_min,
Expand All @@ -63,7 +74,7 @@ def main(params: Optional[List[str]] = None) -> None:


def get_parser() -> ArgumentParser:
parser, _ = _get_cli_parser(features={'read-fc', 'read-modes', 'plotting',
parser, groups = _get_cli_parser(features={'read-fc', 'read-modes', 'plotting',
'q-e', 'btol'})
parser.description = (
'Plots a band structure from the file provided. If a force '
Expand All @@ -77,4 +88,11 @@ def get_parser() -> ArgumentParser:
action='store_true',
help=('Try to determine branch crossings from eigenvectors and'
' rearrange frequencies accordingly'))
groups["plotting"].add_argument(
'--save-web-json',
dest='save_web_json',
default=None,
help='Write JSON file for use with phonon website',
)

return parser
8 changes: 6 additions & 2 deletions euphonic/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
QpointPhononModes, Spectrum1D, Spectrum1DCollection,
Quantity, ureg)
import euphonic.util
Unit = ureg.Unit


def _load_euphonic_json(filename: Union[str, os.PathLike],
Expand Down Expand Up @@ -671,7 +670,7 @@ def __call__(self, parser, args, values, option_string=None):
section.add_argument(
'-s', '--save-to', dest='save_to', default=None,
help='Save resulting plot to a file with this name')
section.add_argument('--title', type=str, default='',
section.add_argument('--title', type=str, default=None,
oerc0122 marked this conversation as resolved.
Show resolved Hide resolved
help='Plot title')
section.add_argument('--x-label', '--xlabel', type=str, default=None,
dest='xlabel', help='Plot x-axis label')
Expand Down Expand Up @@ -934,3 +933,8 @@ def _compose_style(

style.append(explicit_args)
return style


def _get_title(filename: str, title: str | None = None) -> str:
"""Get a plot title: either user-provided string, or from filename"""
return title if title is not None else pathlib.Path(filename).stem
8 changes: 4 additions & 4 deletions euphonic/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def plot_1d(spectra: Union[Spectrum1D,
Spectrum1DCollection,
Sequence[Spectrum1D],
Sequence[Spectrum1DCollection]],
title: str = '',
title: str | None = None,
xlabel: str = '',
ylabel: str = '',
ymin: Optional[float] = None,
Expand Down Expand Up @@ -191,7 +191,7 @@ def plot_1d(spectra: Union[Spectrum1D,
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)

fig.suptitle(title)
fig.suptitle('' if title is None else title)
return fig


Expand Down Expand Up @@ -249,7 +249,7 @@ def plot_2d(spectra: Union[Spectrum2D, Sequence[Spectrum2D]],
vmin: Optional[float] = None,
vmax: Optional[float] = None,
cmap: Optional[Union[str, Colormap]] = None,
title: str = '',
title: str | None = None,
xlabel: str = '',
ylabel: str = '') -> Figure:
"""
Expand Down Expand Up @@ -319,7 +319,7 @@ def _get_minmax_intensity(spectrum: Spectrum2D) -> Tuple[float, float]:
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)

fig.suptitle(title)
fig.suptitle('' if title is None else title)

return fig

Expand Down
4 changes: 3 additions & 1 deletion euphonic/qpoint_phonon_modes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Data container (with methods) for phonon frequencies and eigenvectors"""

import math
from typing import Dict, Optional, Union, TypeVar, Any, Type
from typing import Any, Dict, Optional, Union, Type, TypeVar
from collections.abc import Mapping

import numpy as np
Expand Down
19 changes: 10 additions & 9 deletions euphonic/spectra.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@


CallableQuantity = Callable[[Quantity], Quantity]
XTickLabels = list[tuple[int, str]]


class Spectrum(ABC):
Expand Down Expand Up @@ -84,11 +85,12 @@ def copy(self: T) -> T:
...

@property
def x_tick_labels(self) -> List[Tuple[int, str]]:
def x_tick_labels(self) -> XTickLabels:
"""x-axis tick labels (e.g. high-symmetry point locations)"""
return self._x_tick_labels

@x_tick_labels.setter
def x_tick_labels(self, value: Sequence[Tuple[int, str]]) -> None:
def x_tick_labels(self, value: XTickLabels) -> None:
err_msg = ('x_tick_labels should be of type '
'Sequence[Tuple[int, str]] e.g. '
'[(0, "label1"), (5, "label2")]')
Expand Down Expand Up @@ -171,10 +173,9 @@ def _ranges_from_indices(indices: Union[Sequence[int], np.ndarray]
return ranges

@staticmethod
def _cut_x_ticks(x_tick_labels: Union[Sequence[Tuple[int, str]], None],
def _cut_x_ticks(x_tick_labels: XTickLabels | None,
x0: int,
x1: Union[int, None]) -> Union[List[Tuple[int, str]],
None]:
x1: int | None) -> XTickLabels | None:
"""Crop and shift x labels to new x range"""
if x_tick_labels is None:
return None
Expand Down Expand Up @@ -419,7 +420,7 @@ class Spectrum1D(Spectrum):
T = TypeVar('T', bound='Spectrum1D')

def __init__(self, x_data: Quantity, y_data: Quantity,
x_tick_labels: Optional[Sequence[Tuple[int, str]]] = None,
x_tick_labels: Optional[XTickLabels] = None,
metadata: Optional[Dict[str, Union[int, str]]] = None
) -> None:
"""
Expand Down Expand Up @@ -1147,7 +1148,7 @@ class Spectrum1DCollection(SpectrumCollectionMixin,

def __init__(
self, x_data: Quantity, y_data: Quantity,
x_tick_labels: Optional[Sequence[Tuple[int, str]]] = None,
x_tick_labels: Optional[XTickLabels] = None,
metadata: Optional[Dict[str, Union[str, int, LineData]]] = None
) -> None:
"""
Expand Down Expand Up @@ -1451,7 +1452,7 @@ class Spectrum2D(Spectrum):

def __init__(self, x_data: Quantity, y_data: Quantity,
z_data: Quantity,
x_tick_labels: Optional[Sequence[Tuple[int, str]]] = None,
x_tick_labels: Optional[XTickLabels] = None,
metadata: Optional[Metadata] = None
) -> None:
"""
Expand Down Expand Up @@ -1875,7 +1876,7 @@ class Spectrum2DCollection(SpectrumCollectionMixin,

def __init__(
self, x_data: Quantity, y_data: Quantity, z_data: Quantity,
x_tick_labels: Optional[Sequence[Tuple[int, str]]] = None,
x_tick_labels: Optional[XTickLabels] = None,
metadata: Optional[Metadata] = None
) -> None:
_check_constructor_inputs(
Expand Down
Empty file added euphonic/writers/__init__.py
Empty file.
Loading
Loading