MAJIS OPL reader, exporter and convertor

MAJIS OPL reader, exporter and convertor#

from majis import read_opl, save_opl

Juice observation plan files (OPL) come with two flavors, a legacy one in plain text file in CSV format and a new one in JSON format.

The CSV only contains an observation key, the start and end times, the observation name and the name of the instrument:

# obs_key, start, end, bane, instrument
MAJIS_PRIME_OBSERVATION,2032-12-19T07:10:47Z,2032-12-19T07:19:32Z,MAJ_JUP_DISK_SCAN_ORB17_DES0001,MAJIS
MAJIS_PRIME_OBSERVATION,2032-12-19T07:30:36Z,2032-12-19T07:45:00Z,MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001,MAJIS

Note: The OPL CSV header is often missing.

In the case of the JSON format, a JSON schema is defined by the JUICE SOC here. For example:

{
    "header": {
        "filename": "OPL_example.json",
        "creation_date": "2026-01-01T00:00:00Z",
        "author": "Majis Operations Toolbox"
    },
    "timeline": [
        {
            "name": "MAJ_JUP_DISK_SCAN_ORB17_DES0001",
            "instrument": "MAJIS",
            "type": "OBSERVATION",
            "observation_type": "PRIME",
            "start_time": "2032-12-19T07:10:47Z",
            "end_time": "2032-12-19T07:19:32Z",
        },
        {
            "name": "MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001",
            "instrument": "MAJIS",
            "type": "OBSERVATION",
            "observation_type": "PRIME",
            "start_time": "2032-12-19T07:30:36Z",
            "end_time": "2032-12-19T07:45:00Z",
        },
    ],
}

In this package we try to simplify as much as possible the reader, exporter and convertor of these files.

Read a OPL file#

opl_csv = read_opl('OPL_demo.csv')

opl_csv
event#t_startt_stop
0MAJIS_PRIME_OBSERVATION22032-12-192032-12-19
opl_csv['MAJIS_PRIME_OBSERVATION']
t_startt_endOBS_KEYINSTRUMENTOBSERVATION_TYPETYPE
02032-12-19T07:10:47Z2032-12-19T07:19:32ZMAJ_JUP_DISK_SCAN_ORB17_DES0001MAJISPRIMEOBSERVATION
12032-12-19T07:30:36Z2032-12-19T07:45:00ZMAJ_JUP_AURORAL_MAPPING_ORB17_DES0001MAJISPRIMEOBSERVATION
opl_json = read_opl('OPL_demo.json')

opl_json
event#t_startt_stop
0MAJ_JUP_DISK_SCAN_ORB17_DES0001-2032-12-192032-12-19
1MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001-2032-12-192032-12-19
opl_json['MAJ_JUP_DISK_SCAN_ORB17_DES0001']  # or opl[0]
OBS_KEYMAJ_JUP_DISK_SCAN_ORB17_DES0001
OBS_NAMEMAJ_MAJ_JUP_DISK_SCAN_ORB17_DES0001_ORB17_001
INSTRUMENTMAJIS
TYPEOBSERVATION
OBSERVATION_TYPEPRIME
TARGETplanet.jupiter
t_start2032-12-19T07:10:47Z
t_end2032-12-19T07:19:32Z
POINTINGNADIR_JUPITER
POINTING_DESCRIPTION
POINTING_DESIGNERFalse
DESCRIPTION
SCHEDULING_RULES
INSTRUMENT_AREA{}
PRIMETrue
OPLOPL_demo.json
COMMENTS

Note: by default, in the JSON OPL reader, only the MAJIS blocks are considered. If you need to include other instruments you can add a filter key with the only parameter. It can be a string, a list of string, 'ALL', False or None value.

events = read_opl('OPL_demo.json', only='ALL')

events
event#t_startt_stop
0MAJ_JUP_DISK_SCAN_ORB17_DES0001-2032-12-192032-12-19
1MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001-2032-12-192032-12-19
2GANYMEDE_FLYBY-2033-11-262033-11-27
events['GANYMEDE_FLYBY']
OBS_KEYGANYMEDE_FLYBY
OBS_NAMEWG1_GANYMEDE_FLYBY_OPP_006
INSTRUMENTWG1
TYPEOBSERVATION
OBSERVATION_TYPERIDER
TARGETsatellite.jupiter.ganymede
t_start2033-11-26T19:30:31Z
t_end2033-11-27T19:30:31Z
POINTING
POINTING_DESCRIPTION
POINTING_DESIGNERFalse
DESCRIPTION
SCHEDULING_RULES
INSTRUMENT_AREA{}
PRIMEFalse
OPLOPL_demo.json
COMMENTS

Export an OPL file#

save_opl('OPL_output.csv', opl_json)
MAJIS_PRIME_OBSERVATION,2032-12-19T07:10:47Z,2032-12-19T07:19:32Z,MAJ_JUP_DISK_SCAN_ORB17_DES0001,MAJIS
MAJIS_PRIME_OBSERVATION,2032-12-19T07:30:36Z,2032-12-19T07:45:00Z,MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001,MAJIS
save_opl('OPL_output.json', opl_csv)
{
  "header": {
    "filename": "OPL_output.json",
    "creation_date": "2026-04-29T16:29:56.310Z",
    "author": "docs"
  },
  "timeline": [
    {
      "name": "MAJ_JUP_DISK_SCAN_ORB17_DES0001",
      "start_time": "2032-12-19T07:10:47Z",
      "end_time": "2032-12-19T07:19:32Z",
      "instrument": "MAJIS",
      "observation_type": "PRIME",
      "type": "OBSERVATION",
      "parameters": {}
    },
    {
      "name": "MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001",
      "start_time": "2032-12-19T07:30:36Z",
      "end_time": "2032-12-19T07:45:00Z",
      "instrument": "MAJIS",
      "observation_type": "PRIME",
      "type": "OBSERVATION",
      "parameters": {}
    }
  ]
}

OPL convertors#

It is also possible to convert an OPL CSV to JSON and an OPL JSON to CSV with the convertor functions:

from majis.opl import csv2json_opl, json2csv_opl
csv2json_opl('OPL_output.csv')
PosixPath('OPL_output.json')
!cat OPL_output.csv
MAJIS_PRIME_OBSERVATION,2032-12-19T07:10:47Z,2032-12-19T07:19:32Z,MAJ_JUP_DISK_SCAN_ORB17_DES0001,MAJIS
MAJIS_PRIME_OBSERVATION,2032-12-19T07:30:36Z,2032-12-19T07:45:00Z,MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001,MAJIS

âš ī¸ Be aware that OPL CSV files are very limited and will discard any additional fields present in the JSON input.

json2csv_opl('OPL_output.json')
PosixPath('OPL_output.csv')
!cat OPL_output.json
{
  "header": {
    "filename": "OPL_output.json",
    "creation_date": "2026-04-29T16:29:56.449Z",
    "author": "docs"
  },
  "timeline": [
    {
      "name": "MAJ_JUP_DISK_SCAN_ORB17_DES0001",
      "start_time": "2032-12-19T07:10:47Z",
      "end_time": "2032-12-19T07:19:32Z",
      "instrument": "MAJIS",
      "observation_type": "PRIME",
      "type": "OBSERVATION",
      "parameters": {}
    },
    {
      "name": "MAJ_JUP_AURORAL_MAPPING_ORB17_DES0001",
      "start_time": "2032-12-19T07:30:36Z",
      "end_time": "2032-12-19T07:45:00Z",
      "instrument": "MAJIS",
      "observation_type": "PRIME",
      "type": "OBSERVATION",
      "parameters": {}
    }
  ]
}

âš ī¸ Be aware that OPL CSV files are very limited and only the fields above will be populated (compared with the original OPL_demo.json that contains additional fields).