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
mseed: Avoid invalid warning when guessing endianness of timestamps / UTCDateTime: proper exceptions on invalid 'julday' #1988
Changes from all commits
a11d62a
914034a
7b8d4f6
dfb14c3
10dd640
daf6c47
42a9fbe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
from obspy import UTCDateTime | ||
from obspy.core.compatibility import from_buffer | ||
from obspy.core.util.decorator import ObsPyDeprecationWarning | ||
from . import InternalMSEEDParseTimeError | ||
from .headers import (ENCODINGS, ENDIAN, FIXED_HEADER_ACTIVITY_FLAGS, | ||
FIXED_HEADER_DATA_QUAL_FLAGS, | ||
FIXED_HEADER_IO_CLOCK_FLAGS, HPTMODULUS, | ||
|
@@ -641,6 +642,10 @@ def fmt(s): | |
return native_str('%sHHBBBxHHhhBBBxlxxH' % s) | ||
|
||
def _parse_time(values): | ||
if not (1 <= values[1] <= 366): | ||
msg = 'julday out of bounds (wrong endian?): {!s}'.format( | ||
values[1]) | ||
raise InternalMSEEDParseTimeError(msg) | ||
# The spec says values[5] (.0001 seconds) must be between 0-9999 but | ||
# we've encountered files which have a value of 10000. We interpret | ||
# this as an additional second. The approach here is general enough | ||
|
@@ -653,25 +658,30 @@ def _parse_time(values): | |
"the maximum strictly allowed value is 9999. It will be " | ||
"interpreted as one or more additional seconds." % values[5], | ||
category=UserWarning) | ||
return UTCDateTime( | ||
year=values[0], julday=values[1], | ||
hour=values[2], minute=values[3], second=values[4], | ||
microsecond=msec % 1000000) + offset | ||
try: | ||
t = UTCDateTime( | ||
year=values[0], julday=values[1], | ||
hour=values[2], minute=values[3], second=values[4], | ||
microsecond=msec % 1000000) + offset | ||
except TypeError: | ||
msg = 'Problem decoding time (wrong endian?)' | ||
raise InternalMSEEDParseTimeError(msg) | ||
return t | ||
|
||
if endian is None: | ||
try: | ||
endian = ">" | ||
values = unpack(fmt(endian), data) | ||
starttime = _parse_time(values) | ||
except Exception: | ||
except InternalMSEEDParseTimeError: | ||
endian = "<" | ||
values = unpack(fmt(endian), data) | ||
starttime = _parse_time(values) | ||
else: | ||
values = unpack(fmt(endian), data) | ||
try: | ||
starttime = _parse_time(values) | ||
except Exception: | ||
except InternalMSEEDParseTimeError: | ||
msg = ("Invalid starttime found. The passed byte order is likely " | ||
"wrong.") | ||
raise ValueError(msg) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again pass on exception message. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,6 @@ | |
|
||
import os | ||
import unittest | ||
import warnings | ||
|
||
import numpy as np | ||
|
||
|
@@ -195,13 +194,8 @@ def test_read_obspy(self): | |
# 1 - little endian, 32 bit, version 7 | ||
st1 = read(os.path.join(self.path, | ||
'2011-09-06-1311-36S.A1032_001BH_Z')) | ||
# raises "UserWarning: Record contains a fractional seconds" - ignore | ||
with warnings.catch_warnings(record=True) as w: | ||
warnings.simplefilter('always', UserWarning) | ||
st2 = read(os.path.join(self.path, | ||
'2011-09-06-1311-36S.A1032_001BH_Z.mseed')) | ||
self.assertEqual(len(w), 1) | ||
self.assertEqual(w[0].category, UserWarning) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this no longer necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading this file triggers the invalid warning that I got rid of in mseed reading (i.e. potentially trialing the wrong endian in the first attempt). The only thing that changes in here is that the warning-catching was removed, nothing else. |
||
st2 = read(os.path.join(self.path, | ||
'2011-09-06-1311-36S.A1032_001BH_Z.mseed')) | ||
self.assertEqual(len(st1), len(st2)) | ||
self.assertTrue(np.allclose(st1[0].data, st2[0].data)) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe pass on the message of the exception which would ease debugging and improve understanding of whatever problem is encountered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the message would be very helpful, at least not in the case that seems to be what is normally encountered (when trying the wrong endian):
I'm not sure it would help to see that message to be honest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case this PR is not making things worse. Before it there was a bare try/except, now at least I'm only catching an exception that is explicitly raised inside the subroutine that parses the timestamp.