spdf.py 4 KB
Newer Older
1
2
3
4
5
"""Tools to work with NASA SPDF.

swmfpy.spdf
===========

6
7
Here are a collection of tools to get data from
NASA Goddard's Space Physics Data Facility website.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
"""
__author__ = 'Qusai Al Shidi'
__email__ = 'qusai@umich.edu'

import urllib.request
import datetime as dt
from dateutil import rrule


def get_omni_data(time_from, time_to, **kwargs):
    """Retrieve omni solar wind data over http.

    This will download omni data from https://spdf.gsfc.nasa.gov/pub/data/omni
    and put it into a dictionary. If your data is large, then make a csv and
    use swmfpy.io.read_omni_data().

    Args:
        time_from (datetime.datetime): The start time of the solar wind
                                       data that you want to receive.
        time_to (datetime.datetime): The end time of the solar wind data
                                     you want to receive.

    Returns:
        dict: This will be a list of *all* columns
              available in the omni data set.

    Examples:
        ```python
        import datetime
        import swmfpy.spdf

        from = datetime.datetime(year=2000, month=1, day=1)
        to = datetime.datetime(year=2000, month=2, day=15)
        data = swmfpy.spdf.get_omni_data(from, to)
        ```
    """
44
45
46
    # Author: Qusai Al Shidi
    # Email: qusai@umich.edu

47
    # This is straight from the format guide on spdf
48
    col_names = ('ID for IMF spacecraft',
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
                 'ID for SW Plasma spacecraft',
                 '# of points in IMF averages',
                 '# of points in Plasma averages',
                 'Percent interp',
                 'Timeshift, sec',
                 'RMS, Timeshift',
                 'RMS, Phase front normal',
                 'Time btwn observations, sec',
                 'Field magnitude average, nT',
                 'Bx, nT (GSE, GSM)',
                 'By, nT (GSE)',
                 'Bz, nT (GSE)',
                 'By, nT (GSM)',
                 'Bz, nT (GSM)',
                 'RMS SD B scalar, nT',
                 'RMS SD field vector, nT',
                 'Flow speed, km/s',
                 'Vx Velocity, km/s, GSE',
                 'Vy Velocity, km/s, GSE',
                 'Vz Velocity, km/s, GSE',
                 'Proton Density, n/cc',
                 'Temperature, K',
                 'Flow pressure, nPa',
                 'Electric field, mV/m',
                 'Plasma beta',
                 'Alfven mach number',
                 'X(s/c), GSE, Re',
                 'Y(s/c), GSE, Re',
                 'Z(s/c), GSE, Re',
                 'BSN location, Xgse, Re',
                 'BSN location, Ygse, Re',
80
                 'BSN location, Zgse, Re')
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

    # Set the url
    omni_url = 'https://spdf.gsfc.nasa.gov/pub/data/omni/'
    if kwargs.get('high_res', True):
        omni_url += 'high_res_omni/monthly_1min/'

    # Initialize return dict
    omni_data = {}
    omni_data['Time [UT]'] = []
    for name in col_names:
        omni_data[name] = []

    for date in rrule.rrule(rrule.MONTHLY, dtstart=time_from, until=time_to):
        suffix = 'omni_min'
        suffix += str(date.year) + str(date.month).zfill(2)
        suffix += '.asc'
        data = list(urllib.request.urlopen(omni_url+suffix))

        # Parse omni data
        for line in data:
            cols = line.decode('ascii').split()
            # Time uses day of year which must be parsed
103
104
105
106
            time = dt.datetime.strptime(cols[0] + ' ' +  # year
                                        cols[1] + ' ' +  # day of year
                                        cols[2] + ' ' +  # hour
                                        cols[3],  # minute
107
108
109
110
111
112
113
                                        '%Y %j %H %M')
            if time >= time_from and time <= time_to:
                omni_data['Time [UT]'].append(time)
                # Assign the data from after the time columns (0:3)
                for num, value in enumerate(cols[4:len(col_names)+4]):
                    omni_data[col_names[num]].append(float(value))

114
    return omni_data  # dictionary with omni values where index is the row