diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e640ff5..74ff6d3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: docformatter args: [--in-place, --pre-summary-newline, --make-summary-multi] - repo: https://github.com/myint/autoflake - rev: v1.4 + rev: v1.5.1 hooks: - id: autoflake args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variable'] diff --git a/hvpy/__init__.py b/hvpy/__init__.py index dbb1156..6fe14b1 100644 --- a/hvpy/__init__.py +++ b/hvpy/__init__.py @@ -2,5 +2,5 @@ from .datasource import * from .event import * from .facade import * -from .utils import create_layers +from .utils import create_layers, create_events from .version import __version__ diff --git a/hvpy/tests/test_utils.py b/hvpy/tests/test_utils.py index 7f3d93a..78a335d 100644 --- a/hvpy/tests/test_utils.py +++ b/hvpy/tests/test_utils.py @@ -1,18 +1,22 @@ import pytest -from hvpy import DataSource -from hvpy.utils import _create_layer_string, _to_datasource, create_layers +from hvpy import DataSource, EventType +from hvpy.utils import ( + _create_events_string, + _create_layer_string, + _to_datasource, + _to_event_type, + create_events, + create_layers, +) def test_create_layers(): assert create_layers([(9, 100), (11, 50)]) == "[9,1,100],[11,1,50]" - with pytest.raises(ValueError, match="999 is not a valid DataSource"): create_layers([(9, 100), (999, 100)]) - with pytest.raises(ValueError, match="must be between 0 and 100"): create_layers([(9, 101), (14, 100)]) - with pytest.raises(ValueError, match="must be between 0 and 100"): create_layers([(9, 100), (14, -1)]) @@ -30,3 +34,34 @@ def test_create_layers_string(): _create_layer_string(DataSource.AIA_131, 101) with pytest.raises(ValueError, match="must be between 0 and 100"): _create_layer_string(DataSource.AIA_131, -1) + + +def test_to_event_type(): + assert _to_event_type(EventType.ACTIVE_REGION) == _to_event_type("AR") == EventType.ACTIVE_REGION + + +def test_create_events(): + assert create_events(["ER"]) == "[ER,all,1]" + assert create_events([EventType.ACTIVE_REGION]) == "[AR,all,1]" + assert create_events([(EventType.ACTIVE_REGION, "SPoCA;NOAA_SWPC_Observer")]) == "[AR,SPoCA;NOAA_SWPC_Observer,1]" + assert create_events([EventType.ACTIVE_REGION, EventType.CORONAL_DIMMING]) == "[AR,all,1],[CD,all,1]" + assert ( + create_events([(EventType.ACTIVE_REGION, "ZXCV"), (EventType.CORONAL_DIMMING, "ZXCV")]) + == "[AR,ZXCV,1],[CD,ZXCV,1]" + ) + assert create_events([EventType.ACTIVE_REGION, (EventType.CORONAL_DIMMING, "ASDF")]) == "[AR,all,1],[CD,ASDF,1]" + assert create_events([(EventType.ACTIVE_REGION, "ASDF"), EventType.CORONAL_DIMMING]) == "[AR,ASDF,1],[CD,all,1]" + assert ( + create_events([(EventType.ACTIVE_REGION, "SPoCA"), ("ER", "NOAA_SWPC_Observer")]) + == "[AR,SPoCA,1],[ER,NOAA_SWPC_Observer,1]" + ) + assert create_events([("AR", "SPoCA"), ("ER", "NOAA_SWPC_Observer")]) == "[AR,SPoCA,1],[ER,NOAA_SWPC_Observer,1]" + with pytest.raises(ValueError, match="XYZ is not a valid EventType"): + create_events(["XYZ"]) + with pytest.raises(ValueError, match="is not a EventType or str or two-length tuple"): + create_events([("AR", "SPoCA", 123)]) + + +def test_create_events_string(): + assert _create_events_string(EventType.ACTIVE_REGION) == "[AR,all,1]" + assert _create_events_string(EventType.ACTIVE_REGION, "xyz") == "[AR,xyz,1]" diff --git a/hvpy/utils.py b/hvpy/utils.py index 4956f39..fcc2469 100644 --- a/hvpy/utils.py +++ b/hvpy/utils.py @@ -1,12 +1,14 @@ -from typing import Any, Union, Callable +from typing import Any, List, Union, Callable from datetime import datetime from hvpy.datasource import DataSource +from hvpy.event import EventType __all__ = [ "convert_date_to_isoformat", "convert_date_to_unix", "create_layers", + "create_events", ] @@ -75,3 +77,53 @@ def create_layers(layer: list) -> str: '[3,1,50],[10,1,50]' """ return ",".join([_create_layer_string(_to_datasource(s), o) for s, o in layer]) + + +def _to_event_type(val: Union[str, EventType]) -> EventType: + """ + Validates the input and converts it to a EventType enum. + """ + # This is an undocumented attribute of Enums + if isinstance(val, str) and val in EventType._value2member_map_: + return EventType(val) + elif isinstance(val, EventType): + return val + else: + raise ValueError(f"{val} is not a valid EventType") + + +def _create_events_string(event_type: EventType, recognition_method: str = "all") -> str: + """ + Generates a string of the form "[event_type,recognition_method,1]" for a + event. + """ + return f"[{event_type.value},{recognition_method},1]" + + +def create_events(events: List[Union[EventType, str, tuple]]) -> str: + """ + Creates a string of events separated by commas. + + Parameters + ---------- + events + Either a `list` of `tuple` of the form (``event_type``, ``recognition_methods``), + or a `list` of `str` or `~hvpy.EventType`, e.g., ``["AR", EventType.CORONAL_CAVITY]`` + If ``recognition_methods`` is missing, it will use "ALL". + + Examples + -------- + >>> from hvpy import create_events + >>> create_events(["AR", ("ER", "SPoCA;NOAA_SWPC_Observer")]) + '[AR,all,1],[ER,SPoCA;NOAA_SWPC_Observer,1]' + """ + constructed_events = "" + for event in events: + if isinstance(event, (str, EventType)): + constructed_events += _create_events_string(_to_event_type(event)) + "," + elif isinstance(event, tuple) and len(event) == 2: + constructed_events += _create_events_string(_to_event_type(event[0]), event[1]) + "," + else: + raise ValueError(f"{event} is not a EventType or str or two-length tuple") + # Strips the final comma + return constructed_events[:-1]