Source code for pysatNASA.instruments.timed_guvi

# -*- coding: utf-8 -*-
"""Module for the TIMED GUVI instrument.

Supports the Global UltraViolet Imager (GUVI) instrument on the Thermosphere
Ionosphere Mesosphere Energetics Dynamics (TIMED) satellite data from the
NASA Coordinated Data Analysis Web (CDAWeb).

From JHU APL:

The Global Ultraviolet Imager (GUVI) is one of four instruments that constitute
the TIMED spacecraft, the first mission of the NASA Solar Connections program.
The TIMED spacecraft is being built by Johns Hopkins University Applied Physics
Laboratory and GUVI is a joint collaboration between JHU/APL and the Aerospace
Corporation. TIMED will be used to study the energetics and dynamics of the
Mesosphere and lower Thermosphere between an altitude of approximately 60 to 180
kilometers.

References
----------
Larry J. Paxton, Andrew B. Christensen, David C. Humm, Bernard S. Ogorzalek, C.
Thompson Pardoe, Daniel Morrison, Michele B. Weiss, W. Crain, Patricia H. Lew,
Dan J. Mabry, John O. Goldsten, Stephen A. Gary, David F. Persons, Mark J.
Harold, E. Brian Alvarez, Carl J. Ercol, Douglas J. Strickland, and Ching-I.
Meng "Global ultraviolet imager (GUVI): measuring composition and energy inputs
for the NASA Thermosphere Ionosphere Mesosphere Energetics and Dynamics (TIMED)
mission", Proc. SPIE 3756, Optical Spectroscopic Techniques and Instrumentation
for Atmospheric and Space Research III, (20 October 1999);
https://doi.org/10.1117/12.366380

Properties
----------
platform
    'timed'
name
    'guvi'
tag
    'edr-aur'
    'sdr-imaging'
    'sdr-spectrograph'
inst_id
    ''
    'high_res'
    'low_res'

Warnings
--------
- Currently no cleaning routine.

Example
-------
::

    import pysat
    guvi = pysat.Instrument(platform='timed', name='guvi',
                            inst_id='sdr-imaging', tag='low_res')
    guvi.download(dt.datetime(2005, 6, 28), dt.datetime(2005, 6, 29))
    guvi.load(date=dt.datetime(2005, 6, 28))

"""

import datetime as dt
import functools
import xarray as xr

import pysat
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 jhuapl
from pysatNASA.instruments.methods import timed as mm_timed

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

platform = 'timed'
name = 'guvi'
tags = {'edr-aur': 'Level 2 Auroral disk imaging mode',
        'sdr-imaging': 'Level 1C imaging data',
        'sdr-spectrograph': 'Level 1C spectrograph data'}
inst_ids = {'': ['edr-aur'],
            'high_res': ['sdr-imaging', 'sdr-spectrograph'],
            'low_res': ['sdr-imaging', 'sdr-spectrograph']}

pandas_format = False
multi_file_day = True

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

_test_dates = {
    iid: {tag: dt.datetime(2007 if tag.find('spectrograph') > 0 else 2005, 12,
                           13) for tag in inst_ids[iid]}
    for iid in inst_ids.keys()}
_test_load_opt = {iid: {tag: {'combine_times': True}
                        for tag in inst_ids[iid]}
                  for iid in ['high_res', 'low_res']}
# TODO(#218): Remove when compliant with multi-day load tests
_new_tests = {'high_res': {tag: False for tag in inst_ids['high_res']}}
_clean_warn = {inst_id: {tag: mm_nasa.clean_warnings
                         for tag in inst_ids[inst_id] if tag != 'sdr-imaging'}
               for inst_id in inst_ids.keys()}

# ----------------------------------------------------------------------------
# Instrument methods

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


[docs] def clean(self): """Clean TIMED GUVI imaging data. Note ---- Supports 'clean', 'dusty', 'dirty', 'none'. Method is not called by pysat if clean_level is None or 'none'. """ if self.tag == "sdr-imaging": jhuapl.clean_by_dqi(self) else: # Follow the same warning format as the general clean warning, but # with additional information. pysat.logger.warning(' '.join(['No cleaning routines available for', self.platform, self.name, self.tag, self.inst_id, 'at clean level', self.clean_level])) return
[docs] def concat_data(self, new_data, combine_times=False, **kwargs): """Concatonate data to self.data for TIMED GUVI data. Parameters ---------- new_data : xarray.Dataset or list of such objects New data objects to be concatonated combine_times : bool For SDR data, optionally combine the different datetime coordinates into a single time coordinate (default=False) **kwargs : dict Optional keyword arguments passed to xr.concat Note ---- For xarray, `dim=Instrument.index.name` is passed along to xarray.concat except if the user includes a value for dim as a keyword argument. """ # Establish the time dimensions by data type time_dims = [self.index.name] if self.tag == 'sdr-imaging': time_dims.append('time_auroral') elif self.tag == 'sdr-spectrograph': time_dims.extend(['time_gaim_day', 'time_gaim_night']) # Concatonate using the appropriate method for the number of time # dimensions if len(time_dims) == 1: # There is only one time dimensions, but other dimensions may # need to be adjusted new_data = pysat.utils.coords.expand_xarray_dims( new_data, self.meta, exclude_dims=time_dims) # Combine the data self.data = xr.combine_by_coords(new_data, **kwargs) else: inners = None for ndata in new_data: # Separate into inner datasets inner_keys = {dim: [key for key in ndata.keys() if dim in ndata[key].dims] for dim in time_dims} inner_dat = {dim: ndata.get(inner_keys[dim]) for dim in time_dims} # Add 'single_var's into 'time' dataset to keep track sv_keys = [val.name for val in ndata.values() if 'single_var' in val.dims] singlevar_set = ndata.get(sv_keys) inner_dat[self.index.name] = xr.merge([inner_dat[self.index.name], singlevar_set]) # Concatenate along desired dimension with previous data if inners is None: # No previous data, assign the data separated by dimension inners = dict(inner_dat) else: # Concatenate with existing data inners = {dim: xr.concat([inners[dim], inner_dat[dim]], dim=dim) for dim in time_dims} # Combine all time dimensions if inners is not None: if combine_times: data_list = pysat.utils.coords.expand_xarray_dims( [inners[dim] if dim == self.index.name else inners[dim].rename_dims({dim: self.index.name}) for dim in time_dims if len(inners[dim].dims) > 0], self.meta, dims_equal=False) else: data_list = [inners[dim] for dim in time_dims] # Combine all the data, indexing along time self.data = xr.merge(data_list) return
# ---------------------------------------------------------------------------- # Instrument functions # # Use the default CDAWeb and pysat methods # Set the list_files routine fname = ''.join(('TIMED_GUVI_{lvl:s}{mode:s}_{{year:04d}}{{day:03d}}', '{{hour:02d}}{{minute:02d}}{{second:02d}}-?????????????_REV', '??????_Av{{version:02d}}-??r{{revision:03d}}.nc')) file_lvl = {'low_res': 'L1C-2-disk', 'high_res': 'L1C-disk', '': 'L2B'} mode = {'sdr-imaging': '-IMG', 'sdr-spectrograph': '-SPECT', 'edr-aur': '-edr-aur-IMG'} supported_tags = {inst_id: {tag: fname.format(lvl=file_lvl[inst_id], mode=mode[tag]) for tag in tags.keys()} for inst_id in inst_ids.keys()} list_files = functools.partial(mm_gen.list_files, supported_tags=supported_tags) # Set the download routine url = ''.join(('/pub/data/timed/guvi/levels_v13/{lvl:s}/{mode:s}/', '{{year:4d}}/{{day:03d}}/')) url_lvl = {'sdr-imaging': 'level1c', 'sdr-spectrograph': 'level1c', 'edr-aur': 'level2b'} url_mode = {tag: 'imaging/edr-aur' if tag == 'edr-aur' else tag.split('-')[1] for tag in tags.keys()} download_tags = {iid: {tag: {'remote_dir': url.format(lvl=url_lvl[tag], mode=url_mode[tag]), 'fname': fname.format(lvl=file_lvl[iid], mode=mode[tag])} for tag in tags.keys()} for iid in inst_ids.keys()} download = functools.partial(cdw.download, supported_tags=download_tags) # Set the list_remote_files routine list_remote_files = functools.partial(cdw.list_remote_files, supported_tags=download_tags) # Set the load routine
[docs] def load(fnames, tag='', inst_id='', combine_times=False): """Load TIMED GUVI data into `xarray.DataSet` and `pysat.Meta` objects. This routine is called as needed by pysat. It is not intended for direct user interaction. Parameters ---------- fnames : array-like iterable of filename strings, full path, to data files to be loaded. This input is nominally provided by pysat itself. tag : str tag name used to identify particular data set to be loaded. This input is nominally provided by pysat itself. inst_id : str Satellite ID used to identify particular data set to be loaded. This input is nominally provided by pysat itself. combine_times : bool For SDR data, optionally combine the different datetime coordinates into a single time coordinate (default=False) Returns ------- data : xr.DataSet A xarray DataSet with data prepared for the pysat.Instrument meta : pysat.Meta Metadata formatted for a pysat.Instrument object. Raises ------ ValueError If temporal dimensions are not consistent Note ---- Any additional keyword arguments passed to pysat.Instrument upon instantiation are passed along to this routine. Examples -------- :: inst = pysat.Instrument('timed', 'guvi', inst_id='high_res', tag='sdr-imaging') inst.load(2005, 179) """ if tag == 'edr-aur': data, meta = jhuapl.load_edr_aurora(fnames, tag, inst_id, pandas_format=pandas_format, strict_dim_check=False) else: data, meta = jhuapl.load_sdr_aurora(fnames, name, tag, inst_id, pandas_format=pandas_format, strict_dim_check=False, combine_times=combine_times) return data, meta