Skip to content

Commit

Permalink
Merge pull request #159 from pysat/enh/93_gps
Browse files Browse the repository at this point in the history
ENH: gps instruments and deprecate jpl_gps
  • Loading branch information
jklenzing committed Apr 11, 2023
2 parents d0a8a84 + 6a64f9c commit bb66ff3
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
* DE2 Fabry-Perot Interferometer (FPI)
* DE2 Vector Electric Field Instrument (VEFI) and magnetometer
* DMSP SSUSI EDR-Aurora data
* IGS GPS (TEC and ROTI)
* TIMED GUVI
* Add TIMED GUVI platform to support L1C intensity datasets.
* Type of sensor source handled by inst_id with options of
Expand All @@ -31,6 +32,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
general `init` function
* Added unit tests for the different platform method attributes
* xarray support for TIMED SEE
* Deprecations
* Deprecated jpl_gps instrtument module, moved roti instrument to igs_gps
* Maintenance
* Removed duplicate tests if pysatCDF not isntalled
* Only test pysatCDF on GitHub Actions for older numpy versions
Expand Down
8 changes: 8 additions & 0 deletions docs/supported_instruments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ ICON MIGHTI
.. automodule:: pysatNASA.instruments.icon_mighti
:members:

.. _igs_gps:

IGS GPS
-------

.. automodule:: pysatNASA.instruments.igs_gps
:members:

.. _iss_fpmu:

ISS FPMU
Expand Down
2 changes: 1 addition & 1 deletion pysatNASA/instruments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'de2_lang', 'de2_nacs', 'de2_rpa', 'de2_vefi', 'de2_wats',
'dmsp_ssusi', 'formosat1_ivm',
'icon_euv', 'icon_fuv', 'icon_ivm', 'icon_mighti',
'iss_fpmu', 'jpl_gps', 'omni_hro', 'ses14_gold',
'igs_gps', 'iss_fpmu', 'jpl_gps', 'omni_hro', 'ses14_gold',
'timed_guvi', 'timed_saber', 'timed_see']

for inst in __all__:
Expand Down
133 changes: 133 additions & 0 deletions pysatNASA/instruments/igs_gps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
"""Module for the IGS GPS data products.
Supports GPS data produced from International GNSS Service Total Electron
Content (TEC).
From CDAWeb (modified):
This directory contains the GPS Total Electron Content (TEC) data produced by
the International Global Navigation Satellite Systems Service (IGS) Ionosphere
Working Group and by the Analysis Centers that have contributed to the IGS data
including CODE of the University of Bern (Switzerland), ESA of the European
Space Operations Center (ESOC) in Darmstadt (Germany), JPL of the Jet Propulsion
Laboratory, Pasadena (USA), and UPC of the University Politechnical Catalonia in
Barcelona (Spain). The IGS data are a computed as a weighted mean of the data
from the four analysis centers.
The rate of TEC index (ROTI) characterizes TEC fluctuations observed along
receiver-to-satellite line of sight links over a 5-minute interval.
The measurement is obtained by processing GNSS dual-frequency phase data and
computing the standard deviation of the rate of TEC change over that interval
after removing its background variation trend.
ROTI data are provided as global maps using a 2.5 x 5 degree (geographic
latitude x longitude) grid. The median ROTI value is calculated in each bin.
GNSS data contributing to the ROTI computation are primarily collected from
the global network of International GNSS Service and the regional network of
Continuous Operating Reference Station (CORS).
Properties
----------
platform
'igs'
name
'gps'
tag
['tec', 'roti']
inst_id
['15min', '1hr', '2hr']
Warnings
--------
- The cleaning parameters for the instrument are still under development.
References
----------
M. Hernández-Pajares, J.M. Juan, J. Sanz, R. Orus, A. Garcia-Rigo, J. Feltens,
A. Komjathy, S.C. Schaer, and A. Krankowski, The IGS VTEC maps: a reliable
source of ionospheric information since 1998Journal of Geodesy (2009) 83:263–275
doi:10.1007/s00190-008-0266-1
Feltens, J., M. Angling, N. Jackson‐Booth, N. Jakowski, M. Hoque, M.
Hernández‐Pajares, A. Aragón‐Àngel, R. Orús, and R. Zandbergen (2011),
Comparative testing of four ionospheric models driven with GPS measurements,
Radio Sci., 46, RS0D12, doi:10.1029/2010RS004584
Peng Chen, Hang Liu, Yongchao Ma, Naiquan Zheng, Accuracy and consistency of
different global ionospheric maps released by IGS ionosphere associate analysis
centers, Advances in Space Research, Volume 65, Issue 1, 2020, Pages 163-174,
doi:10.1016/j.asr.2019.09.042.
"""

import datetime as dt
import functools

from pysat.instruments.methods import general as mm_gen

from pysatNASA.instruments.methods import cdaweb as cdw
from pysatNASA.instruments.methods import general as mm_nasa
from pysatNASA.instruments.methods import igs as mm_igs

# ----------------------------------------------------------------------------
# Instrument attributes

platform = 'igs'
name = 'gps'
tags = {'tec': 'Total Electron Content',
'roti': 'Rate of Change in TEC'}
# tags = {'15min': '15 min cadence TEC',
# '1hr': '1 hour cadence TEC',
# '2hr': '2 hour cadence TEC'}
inst_ids = {'15min': ['tec', 'roti'],
'1hr': ['tec'],
'2hr': ['tec']}
pandas_format = False
# ----------------------------------------------------------------------------
# Instrument test attributes

_test_dates = {jj: {kk: dt.datetime(2013, 1, 1) for kk in inst_ids[jj]}
for jj in inst_ids.keys()}
# ----------------------------------------------------------------------------
# Instrument methods


# Use standard init routine
init = functools.partial(mm_nasa.init, module=mm_igs, name=name)


# No cleaning, use standard warning function instead
clean = mm_nasa.clean_warn

# ----------------------------------------------------------------------------
# Instrument functions
#
# Use the default CDAWeb and pysat methods

# Set the list_files routine
cdas_labels = {'15min': {'tec': 'GPS_TEC15MIN_IGS',
'roti': 'GPS_ROTI15MIN_JPL'},
'1hr': {'tec': 'GPS_TEC1HR_IGS'},
'2hr': {'tec': 'GPS_TEC2HR_IGS'}}

date_ver = '{year:4d}{month:02d}{day:02d}_v{version:02d}'
fname = '{cdas:s}_{date_ver:s}.cdf'

supported_tags = {id: {tag: fname.format(cdas=cdas_labels[id][tag].lower(),
date_ver=date_ver)
for tag in inst_ids[id]} for id in inst_ids.keys()}
list_files = functools.partial(mm_gen.list_files,
supported_tags=supported_tags)

# Set the load routine
load = functools.partial(cdw.load, pandas_format=pandas_format)

# Set the download routine
download = functools.partial(cdw.cdas_download, supported_tags=cdas_labels)

# Set the list_remote_files routine
list_remote_files = functools.partial(cdw.cdas_list_remote_files,
supported_tags=cdas_labels)
18 changes: 13 additions & 5 deletions pysatNASA/instruments/jpl_gps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# -*- coding: utf-8 -*-
"""Module for the JPL GPS data products.
.. deprecated:: 0.0.5
This module is now included in igs_gps.py.
This instrument will be removed in 0.1.0+ to reduce redundancy.
Supports ROTI data produced at JPL from International
GNSS Service Total Electron Content (TEC)
Expand Down Expand Up @@ -48,6 +53,7 @@

import datetime as dt
import functools
import warnings

import pysat
from pysat.instruments.methods import general as mm_gen
Expand Down Expand Up @@ -80,6 +86,10 @@ def init(self):
"""

warnings.warn(" ".join(["The instrument module `jpl_gps` has",
"been deprecated and will be removed in 0.1.0+."]),
DeprecationWarning, stacklevel=2)

pysat.logger.info('')
self.acknowledgements = mm_gps.ackn_str
self.references = '\n'.join((mm_gps.refs['mission'],
Expand All @@ -106,11 +116,9 @@ def init(self):
load = functools.partial(cdw.load, pandas_format=pandas_format)

# Set the download routine
basic_tag = {'remote_dir': '/pub/data/gps/roti15min_jpl/{year:4d}/',
'fname': fname}
download_tags = {'': {'roti': basic_tag}}
download = functools.partial(cdw.download, supported_tags=download_tags)
download_tags = {'': {'roti': 'GPS_ROTI15MIN_JPL'}}
download = functools.partial(cdw.cdas_download, supported_tags=download_tags)

# Set the list_remote_files routine
list_remote_files = functools.partial(cdw.list_remote_files,
list_remote_files = functools.partial(cdw.cdas_list_remote_files,
supported_tags=download_tags)
10 changes: 8 additions & 2 deletions pysatNASA/instruments/methods/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@ def init(self, module, name):

# Set references
refs = getattr(module, 'refs')
try:
# See if there is a tag level reference
inst_refs = refs[name][self.tag]
except TypeError:
# No tag-level ref, use name-levele
inst_refs = refs[name]
if 'mission' in refs.keys():
self.references = '\n'.join((refs['mission'], refs[name]))
self.references = '\n'.join((refs['mission'], inst_refs))
else:
self.references = refs[name]
self.references = inst_refs

return

Expand Down
8 changes: 7 additions & 1 deletion pysatNASA/instruments/methods/gps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
"""Provides non-instrument specific routines for JPL ROTI data."""
"""Provides non-instrument specific routines for JPL ROTI data.
.. deprecated:: 0.0.5
This module is now included in `methods.igs`.
This instrument will be removed in 0.1.0+ to reduce redundancy.
"""

ackn_str = ' '.join(("The GPS Total Electron Content (TEC) data",
"produced by the International Global Navigation",
Expand Down
45 changes: 45 additions & 0 deletions pysatNASA/instruments/methods/igs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
"""Provides non-instrument specific routines for JPL ROTI data."""

ackn_str = ' '.join(("The GPS Total Electron Content (TEC) data",
"produced by the International Global Navigation",
"Satellite Systems Service (IGS) Ionosphere Working",
"Group is provided through CDAWeb"))

refs = {'mission': ' '.join(('Feltens J, Schaer S (1998) IGS Products for the',
'Ionosphere, IGS Position Paper. In:',
'Proceedings of the IGS analysis centers',
'workshop, ESOC, Darmstadt, Germany,',
'pp 225–232, 9–11 February')),
'gps': {'tec': ' '.join(('M. Hernández-Pajares, J.M. Juan, J. Sanz, R.',
'Orus, A. Garcia-Rigo, J. Feltens, A.',
'Komjathy, S.C. Schaer, and A. Krankowski,',
'The IGS VTEC maps: a reliable source of',
'ionospheric information since 1998, Journal',
'of Geodesy (2009) 83:263–275',
'doi:10.1007/s00190-008-0266-1.\n',
'Feltens, J., M. Angling, N. Jackson‐Booth,',
'N. Jakowski, M. Hoque, M. Hernández‐Pajares,',
'A. Aragón‐Àngel, R. Orús, and R. Zandbergen',
'(2011), Comparative testing of four',
'ionospheric models driven with GPS',
'measurements, Radio Sci., 46, RS0D12,',
'doi:10.1029/2010RS004584.\n',
'Peng Chen, Hang Liu, Yongchao Ma, Naiquan',
'Zheng, Accuracy and consistency of different',
'global ionospheric maps released by IGS',
'ionosphere associate analysis centers,',
'Advances in Space Research, Volume 65, Issue',
'1, 2020, Pages 163-174,',
'doi:10.1016/j.asr.2019.09.042.\n')),
'roti': ' '.join(('Pi, X., A. J. Mannucci, U. J.',
'Lindqwister, and C. M. Ho, Monitoring of',
'global ionospheric irregularities using',
'the worldwide GPS network, Geophys. Res.',
'Lett., 24, 2283, 1997.\n',
'Pi, X., F. J. Meyer, K. Chotoo, Anthony',
'Freeman, R. G. Caton, and C. T. Bridgwood,',
'Impact of ionospheric scintillation on',
'Spaceborne SAR observations studied using',
'GNSS, Proc. ION-GNSS, pp.1998-2006,',
'2012.'))}}
47 changes: 47 additions & 0 deletions pysatNASA/tests/test_instruments.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

import warnings

import pysat
import pytest

# Make sure to import your instrument library here
import pysatNASA

# Import the test classes from pysat
from pysat.tests.classes import cls_instrument_library as clslib
from pysat.utils import testing

try:
import pysatCDF # noqa: F401
Expand Down Expand Up @@ -93,3 +95,48 @@ def test_load_cdflib(self, inst_dict):
pytest.skip("Download data not available.")

return


class TestDeprecation(object):
"""Unit test for deprecation warnings."""

def setup_method(self):
"""Set up the unit test environment for each method."""

warnings.simplefilter("always", DeprecationWarning)
return

def teardown_method(self):
"""Clean up the unit test environment after each method."""

return

@pytest.mark.parametrize("inst_module,tag", [('jpl_gps', 'roti')])
def test_deprecated_instruments(self, inst_module, tag):
"""Check that instantiating old instruments raises a DeprecationWarning.
Parameters
----------
inst_module : str
name of deprecated module.
tag : str
tag of depracted instrument.
"""

with warnings.catch_warnings(record=True) as war:
pysat.Instrument(inst_module=getattr(pysatNASA.instruments,
inst_module),
tag=tag, use_header=True)

warn_msgs = [" ".join(["The instrument module",
"`{:}`".format(inst_module),
"has been deprecated and will be removed",
"in 0.1.0+."])]

# Ensure the minimum number of warnings were raised.
assert len(war) >= len(warn_msgs)

# Test the warning messages, ensuring each attribute is present.
testing.eval_warnings(war, warn_msgs)
return

0 comments on commit bb66ff3

Please sign in to comment.