Orbit Support
pysat can break satellite data into single orbits on the fly. These orbits will
typically span day breaks, if needed. The Orbits class, which is
treated as a subclass of the Instrument
object, performs these
operations.
Orbit Type
pysat, by default, does not bother to calculate any type of orbit. To use the
orbital methods, information about the orbit needs to be provided at
Instrument
initialization. The index
is the name of the
data to be used for determining orbits, and kind
indicates type of
orbit. There are several orbits to choose from.
kind |
method |
local time |
Uses negative gradients to delineate orbits |
longitude |
Uses negative gradients to delineate orbits |
polar |
Uses sign changes to delineate orbits |
orbit |
Uses any change in value to delineate orbits |
Changes in universal time are also used to delineate orbits. pysat compares any gaps to the supplied orbital period, nominally assumed to be 97 minutes. As orbit periods aren’t constant, a 100% success rate cannot be guaranteed.
import datetime as dt
import pysat
import pysatMadrigal
# Set the type of orbit we want in the Instrument
orbit_info = {'index': 'gdlat', 'kind': 'polar'}
f15 = pysat.Instrument(inst_module=pysatMadrigal.instruments.dmsp_ivm,
tag='utd', inst_id='f15', orbit_info=orbit_info,
clean_level='none')
Loading by Orbit
Orbit determination acts upon data loaded in the f15
object, so to begin we
must load some data (first downloading it if necessary).
day1 = dt.datetime(2011, 12, 31)
day2 = day1 + dt.timedelta(days=1)
if len(f15.files[day1:day2 + dt.timedelta(days=2)]) < 3:
# Download stop time is inclusive
f15.download(start=day1, stop=day2 + dt.timedelta(days=1),
user="Name", password="email")
# To ensure we have a complete first orbit
f15.load(date=day2)
print(f15.index[0], f15.index[-1])
2012-01-01 00:02:09 2012-01-02 00:00:01
Orbits may be selected directly from the attached f15.orbits
class.
The data for the orbit is stored in f15.data
.
f15.orbits[0]
print(f15.index[0], f15.index[-1])
2011-12-31 22:30:37 2011-12-31 22:31:05
f15.orbits[1]
print(f15.index[0], f15.index[-1])
2012-01-01 00:02:09 2012-01-01 00:12:17
Note that getting the first orbit caused pysat to load the day previous, and then back to the current day. There is also a data gap over the change of the year that makes these first two orbits shorter than expected.
Now, you can also move forward an orbit using the Orbits.next()
command:
f15.orbits.next()
print(f15.index[0], f15.index[-1])
2012-01-01 01:03:13 2012-01-01 01:54:01
And back an orbit using the Orbits.prev()
command:
f15.orbits.prev()
print(f15.index[0], f15.index[-1])
2012-01-01 00:12:21 2012-01-01 01:03:09
If we continue to iterate orbits using f15.orbits.next()
the next day
will eventually be loaded to try and form a complete orbit. You can skip the
iteration and just go for the last orbit of a day using indexing:
f15.orbits[-1]
print(f15.index[0], f15.index[-1])
2012-01-01 23:56:41 2012-01-02 00:47:25
pysat loads the next day of data to see if the last orbit on 1 Jan 2012 extends into 2 Jan 2012, which it does. Note that the last orbit of 1 Jan 2012 is the same as the first orbit of 2 Jan 2012. Thus, if we ask for the next orbit,
f15.orbits.next()
print(f15.orbits)
Orbit Settings
--------------
Orbit Kind: 'polar'
Orbit Index: 'gdlat'
Orbit Period: Timedelta('0 days 01:37:00')
Number of Orbits: 29
Loaded Orbit Number: 2
pysat will indicate it is the second orbit of the day. Going back an orbit gives us orbit 30, but referenced to a different day. If 2 Jan 2012 had been loaded, this would be labeled orbit 1.
f15.orbits.prev()
print(f15.orbits)
Orbit Settings
--------------
Orbit Kind: 'polar'
Orbit Index: 'gdlat'
Orbit Period: Timedelta('0 days 01:37:00')
Number of Orbits: 30
Loaded Orbit Number: 30
Orbit iteration is built into Orbits
just like daily iteration is
built into Instrument.load()
(see Iteration).
f15.load(dat=day1)
f15.bounds = (day1, day2)
for f15 in f15.orbits:
print('next available orbit ', f15.data)
next available orbit starts at: 2011-12-31 00:00:05
next available orbit starts at: 2011-12-31 00:28:05
next available orbit starts at: 2011-12-31 01:18:57
next available orbit starts at: 2011-12-31 02:09:49
next available orbit starts at: 2011-12-31 03:00:41
next available orbit starts at: 2011-12-31 03:51:33
next available orbit starts at: 2011-12-31 04:42:25
next available orbit starts at: 2011-12-31 05:33:17
next available orbit starts at: 2011-12-31 06:24:09
next available orbit starts at: 2011-12-31 07:15:01
next available orbit starts at: 2011-12-31 08:05:57
next available orbit starts at: 2011-12-31 08:56:45
next available orbit starts at: 2011-12-31 09:47:37
next available orbit starts at: 2011-12-31 10:38:29
next available orbit starts at: 2011-12-31 11:29:21
next available orbit starts at: 2011-12-31 12:20:13
next available orbit starts at: 2011-12-31 13:11:05
next available orbit starts at: 2011-12-31 14:01:57
next available orbit starts at: 2011-12-31 14:52:53
next available orbit starts at: 2011-12-31 15:43:41
next available orbit starts at: 2011-12-31 16:34:33
next available orbit starts at: 2011-12-31 17:25:25
next available orbit starts at: 2011-12-31 18:16:17
next available orbit starts at: 2011-12-31 19:07:09
next available orbit starts at: 2011-12-31 19:58:05
next available orbit starts at: 2011-12-31 20:48:57
next available orbit starts at: 2011-12-31 21:39:45
next available orbit starts at: 2011-12-31 22:30:37
next available orbit starts at: 2012-01-01 00:02:09
next available orbit starts at: 2012-01-01 00:12:21
next available orbit starts at: 2012-01-01 01:03:13
next available orbit starts at: 2012-01-01 01:54:05
next available orbit starts at: 2012-01-01 02:44:57
next available orbit starts at: 2012-01-01 03:35:49
next available orbit starts at: 2012-01-01 04:26:41
next available orbit starts at: 2012-01-01 05:17:33
next available orbit starts at: 2012-01-01 06:08:29
next available orbit starts at: 2012-01-01 06:59:17
next available orbit starts at: 2012-01-01 07:50:09
next available orbit starts at: 2012-01-01 08:41:01
next available orbit starts at: 2012-01-01 09:31:57
next available orbit starts at: 2012-01-01 10:22:45
next available orbit starts at: 2012-01-01 11:13:41
next available orbit starts at: 2012-01-01 12:04:29
next available orbit starts at: 2012-01-01 12:55:21
next available orbit starts at: 2012-01-01 13:46:13
next available orbit starts at: 2012-01-01 14:37:05
next available orbit starts at: 2012-01-01 15:27:57
next available orbit starts at: 2012-01-01 16:18:53
next available orbit starts at: 2012-01-01 17:09:41
next available orbit starts at: 2012-01-01 18:00:33
next available orbit starts at: 2012-01-01 18:51:25
next available orbit starts at: 2012-01-01 19:42:17
next available orbit starts at: 2012-01-01 20:33:09
next available orbit starts at: 2012-01-01 21:24:05
next available orbit starts at: 2012-01-01 22:14:57
next available orbit starts at: 2012-01-01 23:05:49
next available orbit starts at: 2012-01-01 23:56:41
Ground-Based Instruments
The nominal breakdown of satellite data into discrete orbits isn’t typically as applicable for ground-based instruments, each of which makes exactly one geostationary orbit per day. However, as the orbit iterator triggers off of negative gradients in a variable, a change in sign, or any change in a value, this functionality may be used to break a ground based data set into alternative groupings, as appropriate and desired.
However, should you decide to try and use the pysat.Orbits
class to
break up ground-based data, keep in mind that the orbit iterator defaults to an
orbit period consistent with Low Earth Orbit at Earth. This means that the
expected period of the “orbits” must be provided at Instrument
instantiation. Given the Orbits
heritage, it is assumed that there
is a small amount of variation in the orbital period. pysat will actively
filter “orbits” that are inconsistent with the prescribed orbital period.