Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
4 changes: 1 addition & 3 deletions .github/workflows/test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ name: "Test-Unit"
on:
push:
branches:
- "update-docs-build-and-packaging-setup"
- "unit-testing-with-gh-actions"
- "main"
- "**"
paths:
- "docs/**"
- "pipeline/**"
Expand Down
4 changes: 2 additions & 2 deletions pipeline/infrastructure/casa_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ def format_arg_value(arg_val):
tool_call = '{!s}.{!s}({!s})'.format(fn.__module__, fn.__name__, ', '.join(msg_args))
CASACALLS_LOG.log(level, tool_call)

start_time = datetime.datetime.utcnow()
start_time = datetime.datetime.now(datetime.timezone.utc)
try:
return fn(*args, **kwargs)
finally:
end_time = datetime.datetime.utcnow()
end_time = datetime.datetime.now(datetime.timezone.utc)
elapsed = end_time - start_time
LOG.log(level, '{} CASA tool call took {}s'.format(tool_call, elapsed.total_seconds()))

Expand Down
24 changes: 11 additions & 13 deletions pipeline/infrastructure/renderer/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# *****************************************************************************
import collections
import distutils.spawn as spawn
import shutil
import itertools
import os
import platform
Expand All @@ -33,31 +33,29 @@
LOG = logging.get_logger(__name__)

# Set the command used to shrink plots down to thumbnails. If set to None, no
# thumbnails will be generated
THUMBNAIL_CMD = None
# thumbnails will be generated
THUMBNAIL_CMD = None


# first try to find ImageMagick's 'mogrify' command. We assume that
# ImageMagick's 'convert' commnand can be found in the same directory. We
# ImageMagick's 'convert' command can be found in the same directory. We
# do not search for 'convert' directly as some utilities also provide a
# 'convert' command which may come earlier on the PATH.
mogrify_path = spawn.find_executable('mogrify')
# 'convert' command which may come earlier on the PATH.
mogrify_path = shutil.which('mogrify')
if mogrify_path:
bin_dir = os.path.dirname(mogrify_path)
convert_path = os.path.join(bin_dir, 'convert')
if os.path.exists(convert_path):
LOG.trace('Using convert executable at \'%s\' to generate '
'thumbnails' % convert_path)
THUMBNAIL_CMD = lambda full, thumb : (convert_path, full, '-thumbnail', '250x188', thumb)
LOG.trace("Using convert executable at '%s' to generate thumbnails", convert_path)
THUMBNAIL_CMD = lambda full, thumb: (convert_path, full, '-thumbnail', '250x188', thumb)

if THUMBNAIL_CMD is None and platform.system() == 'Darwin':
# macOS only: fallback to sips if ImageMagick, e.g. from MacPorts or Homebrew is not found on macOS. sips is a system
# executable that should be available on all macOS systems.
sips_path = spawn.find_executable('sips')
sips_path = shutil.which('sips')
if sips_path:
LOG.trace('Using sips executable at \'%s\' to generate thumbnails'
% sips_path)
THUMBNAIL_CMD = lambda full, thumb : (sips_path, '-Z', '250', '--out', thumb, full)
LOG.trace("Using sips executable at '%s' to generate thumbnails", sips_path)
THUMBNAIL_CMD = lambda full, thumb: (sips_path, '-Z', '250', '--out', thumb, full)

if THUMBNAIL_CMD is None:
LOG.warning('Could not find the ImageMagick \'convert\' or macOS \'sips\' command. '
Expand Down
42 changes: 22 additions & 20 deletions pipeline/infrastructure/utils/casa_data_test.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from datetime import datetime
import re
from datetime import datetime, timezone

import pytest

from .. import casa_tools
from .casa_data import (
IERSInfo,
from_mjd_to_datetime,
get_file_md5,
get_iso_mtime,
get_solar_system_model_files,
get_filename_info,
get_iso_mtime,
get_object_info_string,
IERSInfo,
from_mjd_to_datetime
get_solar_system_model_files,
)


# Validation of ISO 8601 strings
REGEX_ISO8601 = (
r'^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T'
Expand Down Expand Up @@ -144,9 +145,9 @@ def test_get_IERS_info():
@skip_if_no_data_repo
def test_validate_date_method():
iers_info = IERSInfo(iers_path=GEODETIC_PATH)
assert iers_info.validate_date(datetime(2020, 12, 1, 0, 0))
assert not iers_info.validate_date(datetime(2021, 12, 1, 0, 0))
assert iers_info.validate_date(datetime(2019, 12, 1, 0, 0))
assert iers_info.validate_date(datetime(2020, 12, 1, 0, 0, tzinfo=timezone.utc))
assert not iers_info.validate_date(datetime(2021, 12, 1, 0, 0, tzinfo=timezone.utc))
assert iers_info.validate_date(datetime(2019, 12, 1, 0, 0, tzinfo=timezone.utc))


@skip_if_no_data_repo
Expand All @@ -155,24 +156,25 @@ def test_string_representation_for_IERS_info():
assert str(iers_info) == (
'IERS table information => {"versions": {"IERSpredict": "0623.0351", '
'"IERSeop2000": "0001.0144"}, "IERSeop2000_last_MJD": 59184.0, '
'"IERSeop2000_last": "2020-12-01 00:00:00", "IERSpredict_last": "2021-04-25 00:00:00"}'
'"IERSeop2000_last": "2020-12-01 00:00:00+00:00", "IERSpredict_last": "2021-04-25 00:00:00+00:00"}'
)


@skip_if_no_data_repo
def test_date_message_type():
iers_info = IERSInfo(iers_path=GEODETIC_PATH)
# Before the end of IERSeop2000
assert iers_info.date_message_type(datetime(2019, 12, 1, 0, 0)) == "GOOD"
assert iers_info.date_message_type(datetime(2019, 12, 1, 0, 0, tzinfo=timezone.utc)) == "GOOD"
# At the end of IERSeop2000
assert iers_info.date_message_type(datetime(2020, 12, 1, 0, 0)) == "GOOD"
assert iers_info.date_message_type(datetime(2020, 12, 1, 0, 0, tzinfo=timezone.utc)) == "GOOD"
# Between the end of IERSeop2000 and IERSeop2000+3 months
assert iers_info.date_message_type(datetime(2020, 12, 2, 0, 0)) == "INFO"
assert iers_info.date_message_type(datetime(2020, 12, 2, 0, 0, tzinfo=timezone.utc)) == "INFO"
# Between IERSeop2000 + 3 months and the end of IERSpredict
assert iers_info.date_message_type(datetime(2021, 3, 25, 0, 0)) == "WARN"
assert iers_info.date_message_type(datetime(2021, 3, 25, 0, 0, tzinfo=timezone.utc)) == "WARN"
# At the end of IERSpredict
assert iers_info.date_message_type(datetime(2021, 4, 25, 0, 0)) == "WARN"
assert iers_info.date_message_type(datetime(2021, 4, 25, 0, 0, tzinfo=timezone.utc)) == "WARN"
# After the end of IERSpredict
assert iers_info.date_message_type(datetime(2021, 12, 1, 0, 0)) == "CRITICAL"
assert iers_info.date_message_type(datetime(2021, 12, 1, 0, 0, tzinfo=timezone.utc)) == "CRITICAL"


def test_date_message_type_when_data_is_not_found():
Expand All @@ -181,7 +183,7 @@ def test_date_message_type_when_data_is_not_found():


def test_from_mjd_to_datetime():
assert from_mjd_to_datetime(59184.0) == datetime(2020, 12, 1, 0, 0)
assert from_mjd_to_datetime(59184.0) == datetime(2020, 12, 1, 0, 0, tzinfo=timezone.utc)


def test_IERSInfo_when_data_is_not_found():
Expand All @@ -199,9 +201,9 @@ def test_get_IERS_info_when_data_is_not_found():

def test_validate_date_method_when_data_is_not_found():
iers_info = IERSInfo(iers_path=WRONG_GEODETIC_PATH)
assert not iers_info.validate_date(datetime(2020, 12, 1, 0, 0))
assert not iers_info.validate_date(datetime(2021, 12, 1, 0, 0))
assert not iers_info.validate_date(datetime(2019, 12, 1, 0, 0))
assert not iers_info.validate_date(datetime(2020, 12, 1, 0, 0, tzinfo=timezone.utc))
assert not iers_info.validate_date(datetime(2021, 12, 1, 0, 0, tzinfo=timezone.utc))
assert not iers_info.validate_date(datetime(2019, 12, 1, 0, 0, tzinfo=timezone.utc))


def test_string_representation_for_IERS_info_when_data_is_not_found():
Expand Down
20 changes: 4 additions & 16 deletions pipeline/infrastructure/utils/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,6 @@ def flatten(l: Sequence[Any]) -> Iterator[Any]:
yield el


def unix_seconds_to_datetime(unix_secs: list[int | float]) -> list[datetime.datetime]:
"""Convert list of UNIX epoch times to a list of equivalent datetime objects.

Args:
unix_secs: list of elapsed seconds since 1970-01-01.
Returns:
List of equivalent Python datetime objects.
"""
return [datetime.datetime.utcfromtimestamp(s) for s in unix_secs]


def mjd_seconds_to_datetime(mjd_secs: list[int | float]) -> list[datetime.datetime]:
"""Convert list of MJD seconds to a list of equivalent datetime objects.

Expand All @@ -197,10 +186,9 @@ def mjd_seconds_to_datetime(mjd_secs: list[int | float]) -> list[datetime.dateti
Returns:
List of equivalent Python datetime objects.
"""
# 1970-01-01 is JD 40587. 86400 = seconds in a day
unix_offset = 40587 * 86400
mjd_secs_with_offsets = [s - unix_offset for s in mjd_secs]
return unix_seconds_to_datetime(mjd_secs_with_offsets)
# MJD epoch is 1858-11-17 00:00:00 UTC
mjd_epoch = datetime.datetime(1858, 11, 17, tzinfo=datetime.timezone.utc)
return [mjd_epoch + datetime.timedelta(seconds=s) for s in mjd_secs]


def get_epoch_as_datetime(epoch: dict) -> datetime.datetime:
Expand All @@ -225,7 +213,7 @@ def get_epoch_as_datetime(epoch: dict) -> datetime.datetime:
t = mt.getvalue(epoch_utc)['m0']
t = qt.sub(t, base_time)
t = qt.convert(t, 's')
t = datetime.datetime.utcfromtimestamp(qt.getvalue(t)[0])
t = datetime.datetime.fromtimestamp(qt.getvalue(t)[0], datetime.timezone.utc)

return t

Expand Down
15 changes: 4 additions & 11 deletions pipeline/infrastructure/utils/conversion_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
mjd_seconds_to_datetime,
range_to_list,
safe_split,
unix_seconds_to_datetime,
)

DomainMock = collections.namedtuple('DomainMock', ['id', 'name'])
Expand Down Expand Up @@ -106,8 +105,10 @@ def test_format_timedelta_raises_exception_too_high_precision():


@pytest.mark.parametrize("inp, expected", [
([1, 2], [datetime.datetime(1858, 11, 17, 0, 0, 1), datetime.datetime(1858, 11, 17, 0, 0, 2)]),
([1, 1.5], [datetime.datetime(1858, 11, 17, 0, 0, 1), datetime.datetime(1858, 11, 17, 0, 0, 1, 500000)]),
([1, 2], [datetime.datetime(1858, 11, 17, 0, 0, 1, tzinfo=datetime.timezone.utc),
datetime.datetime(1858, 11, 17, 0, 0, 2, tzinfo=datetime.timezone.utc)]),
([1, 1.5], [datetime.datetime(1858, 11, 17, 0, 0, 1, tzinfo=datetime.timezone.utc),
datetime.datetime(1858, 11, 17, 0, 0, 1, 500000, tzinfo=datetime.timezone.utc)]),
])
def test_mjd_seconds_to_datetime(inp, expected):
"""Test mjd_seconds_to_datetime()"""
Expand Down Expand Up @@ -136,14 +137,6 @@ def test_safe_split(inp, expected):
assert safe_split(inp) == expected


@pytest.mark.parametrize("inp, expected", [
([1, 1.5], [datetime.datetime(1970, 1, 1, 0, 0, 1), datetime.datetime(1970, 1, 1, 0, 0, 1, 500000)]),
])
def test_unix_seconds_to_datetime(inp, expected):
"""Test unix_seconds_to_datetime()"""
assert unix_seconds_to_datetime(inp) == expected


@pytest.mark.parametrize("inp, expected", [
((None, None), TypeError),
((None, [AntennaMock(id=0, name='Test00'), AntennaMock(id=1, name='Test01')]), [0, 1]),
Expand Down
Loading
Loading