ESA events files#

Recently the ESA-SOC published a collection of event files that contains the different phases of the mission, the dates and names of the flybys; as well as some technical information, e.g. the visibility of the DSN stations and the expected downlinks windows.

Caution

These files need to be considered as experimental and their format and location can evolve significantly in the future. Currently they are only provided for the Juice mission (CREMA 3.0, 5.0 and 5.0b23.1) on the SOC core system toolkit.

New in version 1.1.0: Some of the mission are now translated into fk event kernels that can be loaded with the Juice metakernels. See TourConfig for more details.

Event file format#

An event file is a text file (.csv/.evf/.itl/.orb) containing either a single time event, a start or stop time event or an event with both a start and a stop time.

For example, the mission phases file is defined like this:

Hint

All the events have a t_start and a t_end time and the primary key is stored in the Name column.

You can add comments and blank lines in the the csv file, as long as you keep the column header in the first line (or explicitly mention it in read_events(), see below).

column_0namet_startt_endcolumn_4
Jupiter_Phase_1Approach and first ellipse2031-01-19T19:14:212032-02-08T23:05:31
Jupiter_Phase_2Energy reduction2032-02-08T23:05:322032-06-25T12:23:23
Jupiter_Phase_3Europa flybys2032-06-25T12:23:232032-07-24T07:02:19
Jupiter_Phase_4High-latitude2032-07-24T07:02:192033-08-18T09:43:28
Jupiter_Phase_5Low energy2033-08-18T09:43:282034-12-19T00:00:00
Jupiter_Phase_allAll Jupiter phases2031-01-19T19:14:212034-12-19T00:00:00
Ganymede_Phase_6_1GEOa2034-12-19T00:00:002035-01-17T03:00:00
Ganymede_Phase_6_2GCO50002035-01-17T03:00:002035-04-16T16:00:00
Ganymede_Phase_6_3GEOb2035-04-16T16:00:002035-05-13T02:00:00
Ganymede_Phase_6_4TGCO2035-05-13T02:00:002035-05-21T15:00:00
Ganymede_Phase_6_5GCO5002035-05-21T15:00:002035-09-29T00:00:00
Ganymede_Phase_allAll Ganymede phases2034-12-19T00:00:002035-09-29T00:00:00
Mission_phase_allAll mission phases2031-01-19T19:14:212035-09-29T00:00:00

In some cases, the events are only defined as single event time:

Note

The primary key (Event name) does not need to be unique and will be grouped together.

Here, the XXX_START and XXX_END events will be paired.

If a pair is incomplete, a warning message will be send to the user at runtime.

event nameevent time [utc]contextual info
VISIBILITY_MALARGUE_START2031-01-20T08:03:38Z
DOWNLINK_MALARGUE_START2031-01-20T08:03:38Z
VISIBILITY_GOLDSTONE_START2031-01-20T13:39:08Z
VISIBILITY_GOLDSTONE_END2031-01-20T21:19:41Z
IO_TRANSIT_START2031-01-20T08:44:31Z
IO_TRANSIT_END2031-01-20T10:55:41Z
DOWNLINK_MALARGUE_END2031-01-20T17:03:41Z
VISIBILITY_MALARGUE_END2031-01-20T20:36:11Z
DOWNLINK_MALARGUE_START2031-01-21T08:00:40Z
VISIBILITY_MALARGUE_START2031-01-21T08:00:40Z
GANYMEDE_TRANSIT_START2031-01-21T10:50:31Z
GANYMEDE_TRANSIT_END2031-01-21T11:58:21Z
DOWNLINK_MALARGUE_END2031-01-21T17:00:41Z
VISIBILITY_MALARGUE_END2031-01-21T20:32:41Z
FLYBY_GANYMEDE2031-07-21T07:14:23ZCrema name= 1G1;Time= 21-JUL-2031_07:14:23;Altitude above ganymede [km]= 400.00697;Sub-SC lon [deg]= 238.5;Sub-SC lat [deg]= 2.2;Sub-SC phase [deg]= 84.7;Sub-SC loctime [hours]= 17.6;Jup-Moon-Sc angle [deg]= 119.2;Flight direction= -1Y;Moon true anomalie= 109.1;Ground track velocity [km/s]= 7.1;Velocity wrt sub-sc point radial component [km/s]= 0.0;Velocity wrt sub-sc point tangential component [km/s]= 7.1;Energy generated over +-12h around CA [Wh]= 22369.7;Energy generated over +-1h around CA [Wh]= 879.4;Energy for science over +-12h around CA [Wh]= 8302.5;Energy for science over +-1h around CA [Wh]= -252.5;Relative energy amount for science compared to 6E1 +-12 h= 0.945;Relative energy amount for science compared to 6E1 +-1 h= 0.965;Optimum solar array orientation during pushbroom [deg]= -86.0;PEP-NIM FOV obstruction for optimum solar array [percent]= 0.0;Energy for science over +-1h around CA [Wh] with zero NIM obstruction [Wh]= -1129.4;Maximum sc2sun direction angle to YZ plane during pushbroom= 9.7;Malargue visibility= YES;Cebreros visibility= NO;Delta-time to closest perijove [h]= 13.60
PERIJOVE_1PJ2031-07-21T20:50:23ZDistance to Jupiter [RJ]= 12.30;Sub-SC lon [deg]= 337.7;Sub-SC lat [deg]= 2.4;Sub-SC phase [deg]= 72.7;Sub-SC loctime [hours]= 16.8;Jupiter angular size [deg]= 9.3;Energy generated over +-50h around CA [Wh]= 97198.3;Energy for science over +-50h around CA [Wh]= 37198.3;Relative generated energy amount for science compared to PJ2= 0.975;Malargue visibility= YES;Delta-time to closest moon Flyby= 13.60 hours after the flyby 1G1
FLYBY_GANYMEDE2032-02-13T23:04:51ZCrema name= 2G2;Time= 13-FEB-2032_23:04:51;Altitude above ganymede [km]= 400.04581;Sub-SC lon [deg]= 234.1;Sub-SC lat [deg]= 25.2;Sub-SC phase [deg]= 74.6;Sub-SC loctime [hours]= 16.8;Jup-Moon-Sc angle [deg]= 120.2;Flight direction= 1Y;Moon true anomalie= 115.9;Ground track velocity [km/s]= 5.5;Velocity wrt sub-sc point radial component [km/s]= -0.0;Velocity wrt sub-sc point tangential component [km/s]= 5.5;Energy generated over +-12h around CA [Wh]= 22990.1;Energy generated over +-1h around CA [Wh]= 911.4;Energy for science over +-12h around CA [Wh]= 8923.0;Energy for science over +-1h around CA [Wh]= -220.6;Relative energy amount for science compared to 6E1 +-12 h= 1.016;Relative energy amount for science compared to 6E1 +-1 h= 0.843;Optimum solar array orientation during pushbroom [deg]= -89.0;PEP-NIM FOV obstruction for optimum solar array [percent]= 0.0;Energy for science over +-1h around CA [Wh] with zero NIM obstruction [Wh]= -1130.4;Maximum sc2sun direction angle to YZ plane during pushbroom= 19.2;Malargue visibility= NO;Cebreros visibility= NO;Delta-time to closest perijove [h]= 15.26

When no explicit header is provided in the file. By default we will assume that when it’s the case, the default header should be:

Tip

As you can see below, any custom header can be provided.

namet_startt_endsubgroupworking_group
DL_2031-01-20T08:03:38Z2031-01-20T17:03:41ZGENERIC
DL_2031-01-21T08:00:40Z2031-01-21T17:00:41ZGENERIC
DL_2031-01-22T07:57:12Z2031-01-22T16:57:11ZGENERIC
DL_2031-01-23T07:54:14Z2031-01-23T16:54:11ZGENERIC
DL_2031-01-24T07:50:46Z2031-01-24T16:50:51ZGENERIC
DL_2031-01-25T07:47:48Z2031-01-25T16:47:51ZGENERIC
DL_2031-01-26T07:44:20Z2031-01-26T16:44:21ZGENERIC
DL_2031-01-27T07:41:22Z2031-01-27T16:41:21ZGENERIC
DL_2031-01-28T07:38:24Z2031-01-28T16:38:21ZGENERIC
DL_2031-01-29T07:34:56Z2031-01-29T16:35:01ZGENERIC

MAPPS event file (.evf) are also supported and should follow this pattern:

Note

.evf and .itl files are not currently distributed publicly by the Juice project.

# Example of EVF file for the planetary-coverage documentation
22-JAN-2031_18:54:03    CA_EUROPA      (COUNT =  1)
26-JAN-2031_08:08:00    CA_EUROPA      (COUNT =  2)
29-JAN-2031_21:21:56    CA_EUROPA      (COUNT =  3)

As well as instrument timeline file (.itl):

#-------------------------------------------------------------
# Example of ITL file for the planetary-coverage documentation
#-------------------------------------------------------------

# Timeline version
Version: 1

# Block comment with absolute timing
2032-07-02T04:18:40Z  UVS   OBS_START UVS_SAT_STELL_OCC_A (PRIME=TRUE)
2032-07-02T04:32:00Z  UVS   OBS_END   UVS_SAT_STELL_OCC_A

#==========
# Multi-lines comment block with EVF relative timing (related to `CA_EUROPA.EVF`):
#   29-JAN-2031_21:21:56    CA_EUROPA      (COUNT =  3)
#skip this line (no leading space or tab).
CA_EUROPA (COUNT = 3)  -00:27:00  MAJIS 	OBS_START 		MAJIS_FLYBY_HR_01_001 (PRIME=TRUE)
CA_EUROPA (COUNT = 3)  -00:25:06  MAJIS 	OBS_END 		MAJIS_FLYBY_HR_01_001

# Switch mode absolute block
2031-02-06T00:16:25Z	MAJIS * SWITCH_MODE  	(CURRENT_MODE=SERVICE3 [ENG])

# Switch mode relative block
CA_EUROPA (COUNT = 3)  +04:36:55	MAJIS * SWITCH_MODE  	(CURRENT_MODE=OFF [ENG])

For many space mission, the space agency can provide orbit numbers file (.orb) files than can be used as events files. Usually they are stored in a misc/orbnum/ folder as ancillary kernels files (eg. Juice, Bepi, Cassini…)

 No.     Event UTC PERI       Event SCLK PERI       Orbit Start           Orbit End            SolLon   SolLat   SC Lon   SC Lat      Alt       Inc     Ecc    LonNode  Arg Per    Sol Dist     Semi Axis
=====  ====================  ====================  ====================  ====================  =======  =======  =======  =======  ==========  =======  ======  =======  =======  ============  ===========
    1  2031 JUL 21 20:46:34    1/0288391662.57647  N/A                   2031 NOV 02 02:33:58   267.56    -2.11   340.06     2.42   806508.68    24.48   1.101     6.09   153.67   788073210.9  -8734123.78
    2  2032 FEB 14 14:19:45    1/0306339653.54137  2031 NOV 02 02:33:58  2032 MAR 14 05:22:01   166.97    -1.51   231.43     1.78   841072.16    24.42   0.788     3.52   164.99   776960863.8   4313415.24
    3  2032 APR 11 22:47:53    1/0311294942.33451  2032 MAR 14 05:22:01  2032 APR 26 06:02:38   284.02    -1.31   354.61     0.29   778902.56    25.52   0.687   358.81   180.15   773845024.9   2712784.67
    4  2032 MAY 10 14:44:53    1/0313771562.20434  2032 APR 26 06:02:38  2032 MAY 21 20:13:05   172.88    -1.21   246.50    -0.01   747123.86    25.70   0.644   358.07   186.26   772293776.2   2298334.65
    5  2032 JUN 02 01:35:53    1/0315711422.21023  2032 MAY 21 20:13:05  2032 JUN 10 04:29:47    69.43    -1.13   141.13    -0.01   746701.29    25.70   0.644   358.07   186.24   771083464.1   2298210.38

Parsing an events file#

We recommend to use the generic read_events() function that can parse all ESA events files listed above:

from planetary_coverage import read_events

phases = read_events('Mission_Phases.csv')
timeline = read_events('mission_timeline_event_file_5_0b23_1.csv')
malargue = read_events('segmentation_proposal_Jupiter_Phase_all_crema_5_0b23_1_MALARGUE.csv')
evf = read_events('CA_EUROPA.EVF')
itl = read_events('OTL_EUROPA.ITL', evf='CA_EUROPA.EVF')
orbits = read_events('juice.orb')

If you already know the type of file you want to parse, you can also use CsvEventsFile/EvfEventsFile/ItlEventsFile/OrbitEventsFile parsers:

from planetary_coverage.events import CsvEventsFile

CsvEventsFile('Mission_Phases.csv')
event#t_startt_stop
0Approach and first ellipse-2031-01-192032-02-08
1Energy reduction-2032-02-082032-06-25
2Europa flybys-2032-06-252032-07-24
3High-latitude-2032-07-242033-08-18
4Low energy-2033-08-182034-12-19
5All Jupiter phases-2031-01-192034-12-19
6GEOa-2034-12-192035-01-17
7GCO5000-2035-01-172035-04-16
8GEOb-2035-04-162035-05-13
9TGCO-2035-05-132035-05-21
10GCO500-2035-05-212035-09-29
11All Ganymede phases-2034-12-192035-09-29
12All mission phases-2031-01-192035-09-29
from planetary_coverage.events import EvfEventsFile

EvfEventsFile('CA_EUROPA.EVF')
event#t_startt_stop
CA_EUROPA32031-01-222031-01-29

Hint

The parameter evf is required only for relative timelines.

from planetary_coverage.events import ItlEventsFile

ItlEventsFile('OTL_EUROPA.ITL', evf='CA_EUROPA.EVF')
event#t_startt_stop
OBS22031-01-292032-07-02
SWITCH_MODE22031-01-302031-02-06
from planetary_coverage.events import OrbitEventsFile

OrbitEventsFile('juice.orb')
no.event utc perievent sclk periorbit startorbit endsollonsollatsc lonsc lataltincecclonnodearg persol distsemi axis
12031 JUL 21 20:46:341/0288391662.57647N/A2031 NOV 02 02:33:58267.56-2.11340.062.42806508.6824.481.1016.09153.67788073210.9-8734123.78
22032 FEB 14 14:19:451/0306339653.541372031 NOV 02 02:33:582032 MAR 14 05:22:01166.97-1.51231.431.78841072.1624.420.7883.52164.99776960863.84313415.24
32032 APR 11 22:47:531/0311294942.334512032 MAR 14 05:22:012032 APR 26 06:02:38284.02-1.31354.610.29778902.5625.520.687358.81180.15773845024.92712784.67
42032 MAY 10 14:44:531/0313771562.204342032 APR 26 06:02:382032 MAY 21 20:13:05172.88-1.21246.50-0.01747123.8625.700.644358.07186.26772293776.22298334.65
52032 JUN 02 01:35:531/0315711422.210232032 MAY 21 20:13:052032 JUN 10 04:29:4769.43-1.13141.13-0.01746701.2925.700.644358.07186.24771083464.12298210.38

In all cases, when parsed, you get a collection of Event and EventWindow objects:

phases
event#t_startt_stop
0Approach and first ellipse-2031-01-192032-02-08
1Energy reduction-2032-02-082032-06-25
2Europa flybys-2032-06-252032-07-24
3High-latitude-2032-07-242033-08-18
4Low energy-2033-08-182034-12-19
5All Jupiter phases-2031-01-192034-12-19
6GEOa-2034-12-192035-01-17
7GCO5000-2035-01-172035-04-16
8GEOb-2035-04-162035-05-13
9TGCO-2035-05-132035-05-21
10GCO500-2035-05-212035-09-29
11All Ganymede phases-2034-12-192035-09-29
12All mission phases-2031-01-192035-09-29

Get an event by key#

You can select a given event with its name:

Tip

On Jupyter and IPython environment, you can use the <tab> key to auto-complete: events['<tab> to show the available keys.

gco_500 = phases['GCO500']

gco_500
column_0Ganymede_Phase_6_5
nameGCO500
t_start2035-05-21T15:00:00
t_end2035-09-29T00:00:00
column_4

When multiple event with the same name are detected, they will be grouped in an EventsList:

Tip

The search key is not sensitive to the case.

downlinks = timeline['downlink_malargue']

downlinks
event namet_startt_end
0DOWNLINK_MALARGUE2031-01-20T08:03:38Z2031-01-20T17:03:41Z
1DOWNLINK_MALARGUE2031-01-21T08:00:40Z2031-01-21T17:00:41Z

Hint

In the case of the flybys, they contain a special property (.crema_names) that host they canonic name defined by the SOC:

>>> flybys.crema_names
['1G1', '2G2', ...]
flybys = timeline['FLYBY_GANYMEDE']

flybys
event nameevent time [utc]Crema nameTimeAltitude above ganymede [km]Sub-SC lon [deg]Sub-SC lat [deg]Sub-SC phase [deg]Sub-SC loctime [hours]Jup-Moon-Sc angle [deg]Flight directionMoon true anomalieGround track velocity [km/s]Velocity wrt sub-sc point radial component [km/s]Velocity wrt sub-sc point tangential component [km/s]Energy generated over +-12h around CA [Wh]Energy generated over +-1h around CA [Wh]Energy for science over +-12h around CA [Wh]Energy for science over +-1h around CA [Wh]Relative energy amount for science compared to 6E1 +-12 hRelative energy amount for science compared to 6E1 +-1 hOptimum solar array orientation during pushbroom [deg]PEP-NIM FOV obstruction for optimum solar array [percent]Energy for science over +-1h around CA [Wh] with zero NIM obstruction [Wh]Maximum sc2sun direction angle to YZ plane during pushbroomMalargue visibilityCebreros visibilityDelta-time to closest perijove [h]
0FLYBY_GANYMEDE2031-07-21T07:14:23Z1G121-JUL-2031_07:14:23400.00697238.52.284.717.6119.2-1Y109.17.10.07.122369.7879.48302.5-252.50.9450.965-86.00.0-1129.49.7YESNO13.60
1FLYBY_GANYMEDE2032-02-13T23:04:51Z2G213-FEB-2032_23:04:51400.04581234.125.274.616.8120.21Y115.95.5-0.05.522990.1911.48923.0-220.61.0160.843-89.00.0-1130.419.2NONO15.26

Then, you can select a precise flyby if you want with either its name or its id:

Tip

The value in the contextual info column are also parsed as additional attributes (separated with a ;).

flyby_1G1 = flybys['1G1']  # or flybys[0]

flyby_1G1
event nameFLYBY_GANYMEDE
event time [utc]2031-07-21T07:14:23Z
Crema name1G1
Time21-JUL-2031_07:14:23
Altitude above ganymede [km]400.00697
Sub-SC lon [deg]238.5
Sub-SC lat [deg]2.2
Sub-SC phase [deg]84.7
Sub-SC loctime [hours]17.6
Jup-Moon-Sc angle [deg]119.2
Flight direction-1Y
Moon true anomalie109.1
Ground track velocity [km/s]7.1
Velocity wrt sub-sc point radial component [km/s]0.0
Velocity wrt sub-sc point tangential component [km/s]7.1
Energy generated over +-12h around CA [Wh]22369.7
Energy generated over +-1h around CA [Wh]879.4
Energy for science over +-12h around CA [Wh]8302.5
Energy for science over +-1h around CA [Wh]-252.5
Relative energy amount for science compared to 6E1 +-12 h0.945
Relative energy amount for science compared to 6E1 +-1 h0.965
Optimum solar array orientation during pushbroom [deg]-86.0
PEP-NIM FOV obstruction for optimum solar array [percent]0.0
Energy for science over +-1h around CA [Wh] with zero NIM obstruction [Wh]-1129.4
Maximum sc2sun direction angle to YZ plane during pushbroom9.7
Malargue visibilityYES
Cebreros visibilityNO
Delta-time to closest perijove [h]13.60

Multiple inputs is also supported:

Tip

The events will be sorted by start time and the duplicates will be discarded.

phases['GCO500', 'GCO5000']
event#t_startt_stop
0GCO5000-2035-01-172035-04-16
1GCO500-2035-05-212035-09-29

You can also get all the events starting with a given keyword:

Hint

If only one match is found, the events is directly returned. If you need to the results as an EventsDict you can add the argument: as_dict=True.

timeline.startswith('GANYMEDE')
event nameGANYMEDE_TRANSIT
t_start2031-01-21T10:50:31Z
t_end2031-01-21T11:58:21Z

or ending with a given keyword:

timeline.endswith('TRANSIT')
event#t_startt_stop
0IO_TRANSIT-2031-01-202031-01-20
1GANYMEDE_TRANSIT-2031-01-212031-01-21

as well as complex regular expression:

Note

The find() function is the default function called by __getitem__ in last resort, if none of the key(s) were found.

timeline.find('^VIS.*E$')  # Starting with 'VIS' and ending with a 'E'
event#t_startt_stop
0VISIBILITY_MALARGUE22031-01-202031-01-21
1VISIBILITY_GOLDSTONE-2031-01-202031-01-20

Orbit numbers#

In the case of orbit numbers file (.orb), you can query the orbit number by index, tuple or slice:

orbits[1]  # Tip: negative index are accepted too
no.1
event utc peri2031 JUL 21 20:46:34
event sclk peri1/0288391662.57647
orbit startN/A
orbit end2031 NOV 02 02:33:58
sollon267.56
sollat-2.11
sc lon340.06
sc lat2.42
alt806508.68
inc24.48
ecc1.101
lonnode6.09
arg per153.67
sol dist788073210.9
semi axis-8734123.78
orbits[2, 4]
no.event utc perievent sclk periorbit startorbit endsollonsollatsc lonsc lataltincecclonnodearg persol distsemi axis
022032 FEB 14 14:19:451/0306339653.541372031 NOV 02 02:33:582032 MAR 14 05:22:01166.97-1.51231.431.78841072.1624.420.7883.52164.99776960863.84313415.24
142032 MAY 10 14:44:531/0313771562.204342032 APR 26 06:02:382032 MAY 21 20:13:05172.88-1.21246.50-0.01747123.8625.700.644358.07186.26772293776.22298334.65

Note

Orbit events are defined as single Event object (usually on apo-apsis or peri-apsis point). If you need a time window for a complete orbit, you need to select the starting orbit and the ending orbit in the slice.

We assume that the 1st column of the file correspond to the event time. If you need an other parameter, you can query it with the name of the column.

>>> orbits[1]['sc lon']
340.06
orbits[1:2]  # Note: the last element is always included
no.event utc perievent sclk periorbit startorbit endsollonsollatsc lonsc lataltincecclonnodearg persol distsemi axis
012031 JUL 21 20:46:341/0288391662.57647N/A2031 NOV 02 02:33:58267.56-2.11340.062.42806508.6824.481.1016.09153.67788073210.9-8734123.78
122032 FEB 14 14:19:451/0306339653.541372031 NOV 02 02:33:582032 MAR 14 05:22:01166.97-1.51231.431.78841072.1624.420.7883.52164.99776960863.84313415.24
orbits[1:5:2]  # with step interval
no.event utc perievent sclk periorbit startorbit endsollonsollatsc lonsc lataltincecclonnodearg persol distsemi axis
012031 JUL 21 20:46:341/0288391662.57647N/A2031 NOV 02 02:33:58267.56-2.11340.062.42806508.6824.481.1016.09153.67788073210.9-8734123.78
132032 APR 11 22:47:531/0311294942.334512032 MAR 14 05:22:012032 APR 26 06:02:38284.02-1.31354.610.29778902.5625.520.687358.81180.15773845024.92712784.67
252032 JUN 02 01:35:531/0315711422.210232032 MAY 21 20:13:052032 JUN 10 04:29:4769.43-1.13141.13-0.01746701.2925.700.644358.07186.24771083464.12298210.38

Events filtering#

Tip

You can also use the comparison operators <, <=, >, >=. But you should avoid to chain them (see Danger note below).

The CsvEventsFile, EvfEventsFile, ItlEventsFile, OrbitEventsFile, EventsDict and EventsList can be filtered with any date string with a before(), after() and between() functions:

Hint

If only one match is found, the events is directly returned. If you need to the results as an EventsDict you can add the argument: as_dict=True.

phases.before(2033)  # or: `phases <= 2033`
event#t_startt_stop
0Approach and first ellipse-2031-01-192032-02-08
1Energy reduction-2032-02-082032-06-25
2Europa flybys-2032-06-252032-07-24
phases.after('2034-06-01', strict=True)  # or: `phases > '2034-06-01'`
event#t_startt_stop
0GEOa-2034-12-192035-01-17
1All Ganymede phases-2034-12-192035-09-29
2GCO5000-2035-01-172035-04-16
3GEOb-2035-04-162035-05-13
4TGCO-2035-05-132035-05-21
5GCO500-2035-05-212035-09-29

Caution

  • before() / < / <= perform a comparison with the Event start time.

  • after() / > / >= perform a comparison with the Event stop time.

timeline.between('2031-06', '2032-03')
event#t_startt_stop
0FLYBY_GANYMEDE22031-07-212032-02-13
1PERIJOVE_1PJ-2031-07-212031-07-21

Danger

Unfortunately, it is not possible to chain the operators without explicit parenthesis. You should NOT do:

'2031-06' <= timeline <= '2032-03'

but you should do:

('2031-06' <= timeline) <= '2032-03'

or:

'2031-06' <= (timeline <= '2032-03')

Trim event(s) time boundaries#

If you need to trim the time boundaries of an Event or a collection of Events, you can use the .trim() function. You will get a copy of the event(s) with the same the primary key and properties but with a trimmed start and stop time. The original events are not edited.

Note

The original datetime format is not conserved and you could observed some discrepancies in the datetime string formatting in the output trimmed event. However, the Event start and stop times will always be returned as numpy.datetime64 objects.

downlinks.trim(before='2031-01-20T12:00:00')
event namet_startt_end
0DOWNLINK_MALARGUE2031-01-20T12:00:002031-01-20T17:03:41Z
1DOWNLINK_MALARGUE2031-01-21T08:00:40Z2031-01-21T17:00:41Z

If an element is outside the new time boundary, it will be discarded:

downlinks.trim(after='2031-01-21')
event namet_startt_end
0DOWNLINK_MALARGUE2031-01-20T08:03:38Z2031-01-20T17:03:41Z

You can use both keywords at the same time:

downlinks.trim(before='2031-01-20T12:00:00', after='2031-01-21T12:00:00')
event namet_startt_end
0DOWNLINK_MALARGUE2031-01-20T12:00:002031-01-20T17:03:41Z
1DOWNLINK_MALARGUE2031-01-21T08:00:40Z2031-01-21T12:00:00

or use directly an other event object:

from planetary_coverage.events import EventWindow

event = EventWindow('DUMMY_EVENT', t_start='2031-01-20T12:00:00', t_end='2031-01-21T12:00:00')

downlinks.trim(by_event=event)
event namet_startt_end
0DOWNLINK_MALARGUE2031-01-20T12:00:002031-01-20T17:03:41Z
1DOWNLINK_MALARGUE2031-01-21T08:00:40Z2031-01-21T12:00:00

Events usage#

All these events objects are compatible with TourConfig and Trajectory objects, for example you can use them to select a time window:

tour[gco_500:'1h']
<SpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - UTC start time: 2035-05-21T15:00:00.000
 - UTC stop time: 2035-09-29T00:00:00.000
 - Nb of pts: 3,130

You can also use an event to defined quickly the associated flyby:

tour.flyby(flyby_1G1)
<SpacecraftFlyby> Observer: JUICE | Target: GANYMEDE
 - Altitude at CA: 400.0 km
 - UTC at CA: 2031-07-21T07:08:09
 - Duration: 1 day, 0:00:00
 - Nb of pts: 2,041

You can also get multiple flyby trajectories at once (here the first 3 flybys above Ganymede defined before):

tour.flyby(flybys)
[<SpacecraftFlyby> Observer: JUICE | Target: GANYMEDE
  - Altitude at CA: 400.0 km
  - UTC at CA: 2031-07-21T07:08:09
  - Duration: 1 day, 0:00:00
  - Nb of pts: 2,041,
 <SpacecraftFlyby> Observer: JUICE | Target: GANYMEDE
  - Altitude at CA: 400.0 km
  - UTC at CA: 2032-02-13T23:03:55
  - Duration: 1 day, 0:00:00
  - Nb of pts: 2,041]

Temporal operation is also supported on the Event and EventWindow objects, for example you can take the trajectory 12 hours around a flyby CA event (with a regular temporal step of 10 minutes):

Hint

A subtraction is performed on the start time and an addition is performed on the stop time.

tour[flyby_1G1 - '12 h':flyby_1G1 + '12 h':'10 mins']
<SpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - UTC start time: 2031-07-20T19:14:23.000
 - UTC stop time: 2031-07-21T19:14:23.000
 - Nb of pts: 145

You can also filter a trajectory with any EventWindow or EventsList. Here we choose to take all the tour (from the beginning to the end of the mission with a temporal step of 1h) and we only show the point during the GCO500 phase.

Caution

Filtering on a large temporal windows is very inefficient. Here the full trajectory contains more than 4,500 points when only 130 are really relevant. You should better use the solution presented above:

tour[gco_500:'1 day']

to get the same result in the more efficient way.

tour['start':'stop':'1 day'] & gco_500
<MaskedSpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - First UTC start time: 2035-05-22T00:00:00.000
 - Last UTC stop time: 2035-06-02T23:59:59.999
 - Nb of pts: 13 (+1,584 masked)
 - Nb of segments: 1

New in version 1.1.0

If a fk events kernel is load into the kernel pool, you can query them directly:

tour['GCO500':'1 day']
<SpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - UTC start time: 2035-05-21T15:00:00.000
 - UTC stop time: 2035-09-29T00:00:00.000
 - Nb of pts: 132

Trajectory filtering with events#

Similarly to the ROI, you can also discard an EventWindow or an EventsList. For example if you want to mask all the downlink period, you can do:

traj_no_downlinks = tour['2031-01-20' : '2031-01-22'] ^ downlinks

traj_no_downlinks
<MaskedSpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - First UTC start time: 2031-01-20T00:00:00.000
 - Last UTC stop time: 2031-01-22T00:00:00.000
 - Nb of pts: 1,802 (+1,080 masked)
 - Nb of segments: 3

We can represent the filtered trajectory parameter, with the 2 masked downlink windows:

Hide code cell source
_, ax = plt.subplots(figsize=(14, 3))

ax.plot(traj_no_downlinks.utc, traj_no_downlinks.inc, 'o', ms=2)

y0, y1 = ax.get_ylim()
for downlink in downlinks[:2]:
    ax.fill_between([downlink.start, downlink.stop], y0, y1, color='0.95')
    ax.text(downlink.start + (downlink.stop - downlink.start)/2, (y0 + y1) / 2,
            'Downlink\nwindow', ha='center', va='center')

ax.set_ylim(y0, y1)
ax.set_xlabel('UTC datetime in 2031')
ax.set_ylabel('Incidence angle (degree)');
../_images/4d7ca8d98b491f0c266c76b71bf0884f83008735ada7bf507d26b549e975bd46.png

You can also exclude an EventWindow or an EventsList directly in TourConfig or in the Trajectory definition:

Tip

If you know in advance the events that you want to discard, it is recommended to use this method to avoid creating trajectory points that will not be masked later on. Only the relevant points are kept.

TourConfig(
    mk='5.1 150lb_23_1',
    spacecraft='JUICE',
    target='Ganymede',
    exclude=downlinks,
    version='v422_20230130_002',
)['2031-01-20' : '2031-01-22']
<SpacecraftTrajectory> Observer: JUICE | Target: GANYMEDE
 - UTC start time: 2031-01-20T00:00:00.000
 - UTC stop time: 2031-01-22T00:00:00.000
 - Nb of pts: 1,802