Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
geomag-algorithms
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ghsc
National Geomagnetism Program
geomag-algorithms
Commits
5dae3f10
Commit
5dae3f10
authored
7 years ago
by
Jeremy M Fee
Browse files
Options
Downloads
Patches
Plain Diff
Better estimation of data_time in imfv283
parent
3d317e96
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
geomagio/imfv283/IMFV283Parser.py
+79
-45
79 additions, 45 deletions
geomagio/imfv283/IMFV283Parser.py
test/imfv283_test/IMFV283Parser_test.py
+36
-0
36 additions, 0 deletions
test/imfv283_test/IMFV283Parser_test.py
with
115 additions
and
45 deletions
geomagio/imfv283/IMFV283Parser.py
+
79
−
45
View file @
5dae3f10
...
@@ -2,12 +2,12 @@
...
@@ -2,12 +2,12 @@
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
builtins
import
range
from
builtins
import
range
import
math
import
numpy
import
numpy
import
sys
import
sys
import
obspy
import
obspy
from
obspy.core
import
UTCDateTime
from
datetime
import
datetime
,
timedelta
from
obspy
import
UTCDateTime
from
.
import
imfv283_codes
from
.
import
imfv283_codes
# values that represent missing data points in IAGA2002
# values that represent missing data points in IAGA2002
...
@@ -99,6 +99,73 @@ class IMFV283Parser(object):
...
@@ -99,6 +99,73 @@ class IMFV283Parser(object):
sys
.
stderr
.
write
(
"
Incorrect data line
"
)
sys
.
stderr
.
write
(
"
Incorrect data line
"
)
sys
.
stderr
.
write
(
line
)
sys
.
stderr
.
write
(
line
)
def
_estimate_data_time
(
self
,
transmission
,
doy
,
minute
,
max_transmit_delay
=
1800
):
"""
Get data start time for a GOES data packet.
Parameters
----------
transmission : str
goes transmission time in format
'
YYDDDHHMMSS
'
, where
YY is 2 digit year (assumed to be years since 2000)
DDD is julian year day
HH is hour of day (24 hour clock)
MM is minute of day
SS is second of day
doy : int
day of year for first data sample
minute : int
minute of day for first data sample
max_transmit_delay : int
maximum delay in seconds between doy+minute and transmission
before attempting to correct gps timing errors.
default 1800 (30 minutes)
Returns
-------
data_time : UTCDateTime
estimated time of first data sample
transmit_time : UTCDateTime
time when message was transmitted
corrected : bool
whether a gps timing error was corrected
"""
# convert to datetime
transmit_time
=
UTCDateTime
(
'
20
'
+
transmission
[
0
:
5
]
+
'
T
'
+
transmission
[
5
:])
transmit_year
=
transmit_time
.
year
# delta should not include first day of year
data_time_delta
=
timedelta
(
days
=
doy
-
1
,
minutes
=
minute
)
data_time
=
UTCDateTime
(
datetime
(
transmit_year
,
1
,
1
)
+
data_time_delta
)
if
data_time
>
transmit_time
:
# data cannot be measured after it is transmitted
data_time
=
UTCDateTime
(
datetime
(
transmit_year
-
1
,
1
,
1
))
+
\
data_time_delta
# check transmission delay, to detect gps clock errors
transmit_delay
=
transmit_time
-
data_time
if
transmit_delay
<
max_transmit_delay
:
return
(
data_time
,
transmit_time
,
False
)
# otherwise, try to correct gps timing errors
if
transmit_year
>=
1999
:
# on 1999-08-22, gps clocks reset to 1980-01-06
# 228 = (UTCDateTime('1999-08-22') - UTCDateTime('1999-01-06')) \
# / (24 * 60 * 60)
corrected_data_time
=
data_time
+
timedelta
(
days
=
228
)
transmit_delay
=
transmit_time
-
corrected_data_time
if
transmit_delay
<
max_transmit_delay
:
return
(
corrected_data_time
,
transmit_time
,
True
)
if
transmit_year
>=
2019
:
# on 2019-04-07, gps clocks reset to 1980-01-06
# 91 = (UTCDateTime('2019-04-07') - UTCDateTime('2019-01-06')) \
# / (24 * 60 * 60)
corrected_data_time
=
data_time
+
timedelta
(
days
=
91
)
transmit_delay
=
transmit_time
-
corrected_data_time
if
transmit_delay
<
max_transmit_delay
:
return
(
corrected_data_time
,
transmit_time
,
True
)
# otherwise return reported data_time
return
(
data_time
,
transmit_time
,
False
)
def
_get_data
(
self
,
header
,
data
):
def
_get_data
(
self
,
header
,
data
):
"""
get data from data packet
"""
get data from data packet
...
@@ -155,47 +222,6 @@ class IMFV283Parser(object):
...
@@ -155,47 +222,6 @@ class IMFV283Parser(object):
return
HEADER_SIZE
+
1
return
HEADER_SIZE
+
1
return
HEADER_SIZE
return
HEADER_SIZE
def
_get_startime
(
self
,
msg_header
,
goes_header
):
"""
Get Starttime by combining headers.
Parameters
----------
msg_header : dict
header information for the message packet
goes_header : dict
header information for the goes data packet
Returns
-------
goes_time : UTCDateTime
The starttime for the goes data packet.
msg_time : UTCDateTime
The starttime for the goes message packet.
Notes
-----
The goes data packet stores the day of the year, and the minute of
the day. To get a complete starttime, we use the year for the message
and correct for the case where the message came in a new year, vs.
when the data packet was created.
"""
msg_time
=
msg_header
[
'
transmission_time
'
]
msg_year
=
2000
+
int
(
msg_time
[
0
:
2
])
msg_day
=
int
(
msg_time
[
2
:
5
])
oridinal_time
=
'
%04d%sT%s
'
%
(
msg_year
,
msg_time
[
2
:
5
],
msg_time
[
5
:])
msg_time
=
UTCDateTime
(
oridinal_time
)
if
msg_day
==
1
and
goes_header
[
'
day
'
]
>=
365
:
msg_year
-=
1
hour
=
math
.
floor
(
goes_header
[
'
minute
'
]
/
60.
)
minute
=
goes_header
[
'
minute
'
]
%
60
ordinal_time
=
'
%04d%03dT%02d%02d
'
%
(
msg_year
,
goes_header
[
'
day
'
],
hour
,
minute
)
goes_time
=
UTCDateTime
(
ordinal_time
)
return
(
goes_time
,
msg_time
)
def
_parse_goes_header
(
self
,
data
):
def
_parse_goes_header
(
self
,
data
):
"""
parse goes data header
"""
parse goes data header
...
@@ -278,9 +304,17 @@ class IMFV283Parser(object):
...
@@ -278,9 +304,17 @@ class IMFV283Parser(object):
parsed header of the goes data
parsed header of the goes data
"""
"""
(
goes_time
,
msg_time
)
=
self
.
_get_startime
(
msg_header
,
goes_header
)
(
goes_time
,
msg_time
,
corrected
)
=
self
.
_estimate_data_time
(
msg_header
[
'
transmission_time
'
],
goes_header
[
'
day
'
],
goes_header
[
'
minute
'
])
if
corrected
:
sys
.
stderr
.
write
(
'
corrected gps week number error
\n
'
+
'
\t
transmit day={}, reported day={}, corrected day={}
\n
'
.
format
(
msg_time
.
julday
,
goes_header
[
'
day
'
],
goes_time
.
julday
))
if
(
msg_time
-
goes_time
)
>
(
24
*
60
):
if
(
msg_time
-
goes_time
)
>
(
24
*
60
):
sys
.
stderr
.
write
(
'
data over twice as old as the message
'
)
sys
.
stderr
.
write
(
'
data over twice as old as the message
\n
'
)
return
return
scale
=
goes_header
[
'
scale
'
]
scale
=
goes_header
[
'
scale
'
]
...
...
This diff is collapsed.
Click to expand it.
test/imfv283_test/IMFV283Parser_test.py
+
36
−
0
View file @
5dae3f10
"""
Tests for the IMFV283 Parser class.
"""
"""
Tests for the IMFV283 Parser class.
"""
from
nose.tools
import
assert_equals
from
nose.tools
import
assert_equals
from
obspy
import
UTCDateTime
from
geomagio.imfv283
import
IMFV283Parser
,
imfv283_codes
from
geomagio.imfv283
import
IMFV283Parser
,
imfv283_codes
...
@@ -33,3 +35,37 @@ def test_parse_goes_header():
...
@@ -33,3 +35,37 @@ def test_parse_goes_header():
191
)
191
)
goes_header
=
IMFV283Parser
().
_parse_goes_header
(
goes_data
)
goes_header
=
IMFV283Parser
().
_parse_goes_header
(
goes_data
)
assert_equals
(
goes_header
[
'
day
'
],
23
)
assert_equals
(
goes_header
[
'
day
'
],
23
)
def
test_estimate_data_time__correct_doy
():
"""
imfv283_test.IMFV283Parser_test.test_estimate_data_time__correct_doy()
Use example goes packet from BOU station, with correct goes doy value.
"""
parser
=
IMFV283Parser
()
# BOU aka normal
transmission
=
'
17274013121
'
day
=
274
minute
=
72
(
data_time
,
transmit_time
,
corrected
)
=
\
parser
.
_estimate_data_time
(
transmission
,
day
,
minute
)
assert_equals
(
data_time
,
UTCDateTime
(
'
2017-10-01T01:12:00Z
'
))
assert_equals
(
transmit_time
,
UTCDateTime
(
'
2017-10-01T01:31:21Z
'
))
assert_equals
(
corrected
,
False
)
def
test_estimate_data_time__incorrect_doy
():
"""
imfv283_test.IMFV283Parser_test.test_estimate_data_time__correct_doy()
Use example goes packet from BLC station, with incorrect goes doy value.
"""
parser
=
IMFV283Parser
()
# BLC aka 1999 rollover gps issue
transmission
=
'
17274013241
'
day
=
46
minute
=
78
(
data_time
,
transmit_time
,
corrected
)
=
\
parser
.
_estimate_data_time
(
transmission
,
day
,
minute
)
assert_equals
(
data_time
,
UTCDateTime
(
'
2017-10-01T01:18:00Z
'
))
assert_equals
(
transmit_time
,
UTCDateTime
(
'
2017-10-01T01:32:41Z
'
))
assert_equals
(
corrected
,
True
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment