PlanetaryPy
================

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

Potential
logo:![image.png](images/epilup_with_python_logo_with_axis.png)

## Install

``` bash
pip install planetarypy
```

This will pull in these other dependencies and their dependencies:

`tomlkit pandas pvl numpy python-dateutil tqdm lxml yarl hirise-tools kalasiris`

## Suggested standard abbreviations:

- Inside these docs the package will be called `PLPY` for brevity.
- A standard Python import could be: `plp` or `plpy`
  - because the last `p` in `plp` can be pronounced out, we consider
    these equivalent for human conversation and pronounce these
    “plippy”.

## General scope

First and foremost this package should provide support in working with
planetary science data.

With `working` we mean:

- locating
- retrieving
- reading
- further processing

of data.

### Locating

This library manages, via its `PDS tools`, multiple PDS3 index files per
instrument that can be used for identifying data of interest. These
index files are automatically downloaded and converted to the very
performant (and cloud-ready)
[parquet](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_parquet.html)
file format. \> Parquet is able to store advanced datatypes like
nan-capable integer and full datetime objects, as opposed to HDF5.

### Retrieving

The interface to getting data is via a path-retrieving function based on
a PDS product-id. If that product-id is available locally, the path will
be returned. If it is not, it will previously be downloaded, stored in a
systematic fashion organized by mission and instrument, and then the
local path will be returned.

### Reading

For now, the library only returns the path to the object and the user
needs to sort out the reading process. A recently funded NASA project
`Planetary Data Reader` will be integrated here, so that basic reading
into memory can be provided.

As such, we anticipate two classes of reading support: 1. basic reading
into numpy and/or xarray 1. added reader functionality like basic plots
and basic geospatial processing, as supported by interested parties

There will exist larger other packages that focus on working with a
given instrument’s data, in which case that package could become an
affiliated package with the `planetarypy` GitHub organization, if so
desired.

### Further processing

In the future, additional frequently used procedures will be added to
this library, e.g. \* frequently used GDAL/rasterio procedures \*
frequently used SPICE operations \* like surface illumination on a given
body

## PDS tools

Look at the `Apps` docs to see what `pds.apps` exist for easily getting
PDS indexes. The `find_index` app is specifically useful when you don’t
know what index files exist.

So far, the following indexes are supported (but not necessarily all
tested within PLPY):

- Cassini
  - ISS (all)
  - UVIS (all)
- MRO
  - CTX EDR
  - HiRISE
    - EDR, RDR, DTM
      - EDR index has a bug (as delivered by the team, reported), where
        I need to activate an existing fix for it.
- LRO
  - Diviner (DLRE)
    - EDR, RDR
  - LOLA
    - EDR, RDR

### More indexes

More indexes of other instruments can be easily added by following the
existing structure of what has been copied into your config at
`~/.planetarypy_config.toml`.

Please consider submitting a pull request for adding further PDS index
files into the config file at its source:
https://github.com/michaelaye/nbplanetary/blob/master/planetarypy/data/planetarypy_config.toml

## Utils

Find something in `Utils` for working with NASA timestamps and a well
working URL download function
[`url_retrieve`](https://michaelaye.github.io/planetarypy/utils.html#url_retrieve),
among other stuff.

## Experiment/Instrument Specific

So far, `planetarypy` supports CTX EDR and HiRISE RGB.NOMAP data. Look
at the `CTX` and `HiRISE` pages for descriptions of classes for working
with these data.

## Bug reports

Please submit bug reports at
https://github.com/michaelaye/nbplanetary/issues

## How to use

### Indexes

See [PDS apps](02c_pds.apps.ipynb) for more details.

``` python
from planetarypy.pds.apps import get_index
```

``` python
ctrindex = get_index("mro.ctx", "edr")
ctrindex.sample(5, random_state=42)  # setting random_state to always get same files for docs
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>VOLUME_ID</th>
      <th>FILE_SPECIFICATION_NAME</th>
      <th>ORIGINAL_PRODUCT_ID</th>
      <th>PRODUCT_ID</th>
      <th>IMAGE_TIME</th>
      <th>INSTRUMENT_ID</th>
      <th>INSTRUMENT_MODE_ID</th>
      <th>LINE_SAMPLES</th>
      <th>LINES</th>
      <th>SPATIAL_SUMMING</th>
      <th>...</th>
      <th>SUB_SOLAR_LATITUDE</th>
      <th>SUB_SPACECRAFT_LONGITUDE</th>
      <th>SUB_SPACECRAFT_LATITUDE</th>
      <th>SOLAR_DISTANCE</th>
      <th>SOLAR_LONGITUDE</th>
      <th>LOCAL_TIME</th>
      <th>IMAGE_SKEW_ANGLE</th>
      <th>RATIONALE_DESC</th>
      <th>DATA_QUALITY_DESC</th>
      <th>ORBIT_NUMBER</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>33054</th>
      <td>MROX_1189</td>
      <td>DATA/G01_018691_2639_XN_83N125W.IMG</td>
      <td>4A_04_105C021D00</td>
      <td>G01_018691_2639_XN_83N125W</td>
      <td>2010-07-22 22:26:50.279</td>
      <td>CTX</td>
      <td>NIFL</td>
      <td>5056</td>
      <td>7168</td>
      <td>1</td>
      <td>...</td>
      <td>21.37</td>
      <td>125.18</td>
      <td>83.96</td>
      <td>240053143.9</td>
      <td>122.10</td>
      <td>13.69</td>
      <td>89.9</td>
      <td>Ride-along with HiRISE</td>
      <td>OK</td>
      <td>18691</td>
    </tr>
    <tr>
      <th>93213</th>
      <td>MROX_2936</td>
      <td>DATA/J18_051799_1768_XN_03S008W.IMG</td>
      <td>4A_04_1106006B00</td>
      <td>J18_051799_1768_XN_03S008W</td>
      <td>2017-08-14 16:52:08.694</td>
      <td>CTX</td>
      <td>NIFL</td>
      <td>5056</td>
      <td>7168</td>
      <td>1</td>
      <td>...</td>
      <td>18.43</td>
      <td>8.94</td>
      <td>-3.30</td>
      <td>247073409.4</td>
      <td>47.31</td>
      <td>14.79</td>
      <td>90.1</td>
      <td>Ride-along with HiRISE</td>
      <td>OK</td>
      <td>51799</td>
    </tr>
    <tr>
      <th>116150</th>
      <td>MROX_3682</td>
      <td>DATA/N07_065025_2026_XN_22N001W.IMG</td>
      <td>4A_04_114A010700</td>
      <td>N07_065025_2026_XN_22N001W</td>
      <td>2020-06-10 06:19:59.533</td>
      <td>CTX</td>
      <td>NIFL</td>
      <td>5056</td>
      <td>52224</td>
      <td>1</td>
      <td>...</td>
      <td>-15.04</td>
      <td>0.80</td>
      <td>22.71</td>
      <td>209715242.3</td>
      <td>217.08</td>
      <td>15.65</td>
      <td>89.7</td>
      <td>Ride-along with CRISM</td>
      <td>OK</td>
      <td>65025</td>
    </tr>
    <tr>
      <th>84411</th>
      <td>MROX_2710</td>
      <td>DATA/J06_047059_1670_XN_13S194W.IMG</td>
      <td>4A_04_10EE015900</td>
      <td>J06_047059_1670_XN_13S194W</td>
      <td>2016-08-10 07:59:51.331</td>
      <td>CTX</td>
      <td>NIFL</td>
      <td>2336</td>
      <td>16384</td>
      <td>1</td>
      <td>...</td>
      <td>-9.00</td>
      <td>194.58</td>
      <td>-13.04</td>
      <td>213104117.6</td>
      <td>201.30</td>
      <td>15.46</td>
      <td>90.2</td>
      <td>Landforms near Al Qahira Vallis</td>
      <td>OK</td>
      <td>47059</td>
    </tr>
    <tr>
      <th>93055</th>
      <td>MROX_2931</td>
      <td>DATA/J17_051369_1512_XI_28S145W.IMG</td>
      <td>4A_04_110500C700</td>
      <td>J17_051369_1512_XI_28S145W</td>
      <td>2017-07-12 04:36:20.503</td>
      <td>CTX</td>
      <td>ITL</td>
      <td>5056</td>
      <td>7168</td>
      <td>1</td>
      <td>...</td>
      <td>13.27</td>
      <td>146.43</td>
      <td>-28.94</td>
      <td>243673970.8</td>
      <td>32.23</td>
      <td>14.74</td>
      <td>90.1</td>
      <td>Sirenum Fossae trough cut through landslide de...</td>
      <td>OK</td>
      <td>51369</td>
    </tr>
  </tbody>
</table>
<p>5 rows × 51 columns</p>
</div>

``` python
hirise_rdr = get_index("mro.hirise", "rdr")
hirise_rdr.sample(5, random_state=42)
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>VOLUME_ID</th>
      <th>FILE_NAME_SPECIFICATION</th>
      <th>INSTRUMENT_HOST_ID</th>
      <th>INSTRUMENT_ID</th>
      <th>OBSERVATION_ID</th>
      <th>PRODUCT_ID</th>
      <th>PRODUCT_VERSION_ID</th>
      <th>TARGET_NAME</th>
      <th>ORBIT_NUMBER</th>
      <th>MISSION_PHASE_NAME</th>
      <th>...</th>
      <th>LINE_PROJECTION_OFFSET</th>
      <th>SAMPLE_PROJECTION_OFFSET</th>
      <th>CORNER1_LATITUDE</th>
      <th>CORNER1_LONGITUDE</th>
      <th>CORNER2_LATITUDE</th>
      <th>CORNER2_LONGITUDE</th>
      <th>CORNER3_LATITUDE</th>
      <th>CORNER3_LONGITUDE</th>
      <th>CORNER4_LATITUDE</th>
      <th>CORNER4_LONGITUDE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>17724</th>
      <td>MROHR_0001</td>
      <td>RDR/PSP/ORB_010500_010599/PSP_010580_2115/PSP_...</td>
      <td>MRO</td>
      <td>HIRISE</td>
      <td>PSP_010580_2115</td>
      <td>PSP_010580_2115_RED</td>
      <td>2</td>
      <td>MARS</td>
      <td>10580</td>
      <td>Primary Science Phase</td>
      <td>...</td>
      <td>7363560.0</td>
      <td>-25472900.0</td>
      <td>30.9561</td>
      <td>304.379</td>
      <td>30.9448</td>
      <td>304.262</td>
      <td>31.0917</td>
      <td>304.240</td>
      <td>31.1030</td>
      <td>304.358</td>
    </tr>
    <tr>
      <th>2964</th>
      <td>MROHR_0001</td>
      <td>RDR/PSP/ORB_003500_003599/PSP_003519_0950/PSP_...</td>
      <td>MRO</td>
      <td>HIRISE</td>
      <td>PSP_003519_0950</td>
      <td>PSP_003519_0950_RED</td>
      <td>2</td>
      <td>MARS</td>
      <td>3519</td>
      <td>Primary Science Phase</td>
      <td>...</td>
      <td>-554006.0</td>
      <td>13544.5</td>
      <td>-85.2476</td>
      <td>181.385</td>
      <td>-85.3015</td>
      <td>180.594</td>
      <td>-85.1038</td>
      <td>178.725</td>
      <td>-85.0520</td>
      <td>179.504</td>
    </tr>
    <tr>
      <th>53360</th>
      <td>MROHR_0001</td>
      <td>RDR/ESP/ORB_028900_028999/ESP_028997_0945/ESP_...</td>
      <td>MRO</td>
      <td>HIRISE</td>
      <td>ESP_028997_0945</td>
      <td>ESP_028997_0945_COLOR</td>
      <td>1</td>
      <td>MARS</td>
      <td>28997</td>
      <td>Extended Science Phase</td>
      <td>...</td>
      <td>-124310.0</td>
      <td>-508464.0</td>
      <td>-85.5280</td>
      <td>105.028</td>
      <td>-85.5372</td>
      <td>104.843</td>
      <td>-85.2871</td>
      <td>102.919</td>
      <td>-85.2784</td>
      <td>103.098</td>
    </tr>
    <tr>
      <th>81502</th>
      <td>MROHR_0001</td>
      <td>RDR/ESP/ORB_044700_044799/ESP_044724_1480/ESP_...</td>
      <td>MRO</td>
      <td>HIRISE</td>
      <td>ESP_044724_1480</td>
      <td>ESP_044724_1480_COLOR</td>
      <td>1</td>
      <td>MARS</td>
      <td>44724</td>
      <td>Extended Science Phase</td>
      <td>...</td>
      <td>-3727530.0</td>
      <td>-1381090.0</td>
      <td>-31.8762</td>
      <td>193.542</td>
      <td>-31.8781</td>
      <td>193.521</td>
      <td>-31.4914</td>
      <td>193.472</td>
      <td>-31.4895</td>
      <td>193.493</td>
    </tr>
    <tr>
      <th>119683</th>
      <td>MROHR_0001</td>
      <td>RDR/ESP/ORB_059200_059299/ESP_059292_1310/ESP_...</td>
      <td>MRO</td>
      <td>HIRISE</td>
      <td>ESP_059292_1310</td>
      <td>ESP_059292_1310_RED</td>
      <td>1</td>
      <td>MARS</td>
      <td>59292</td>
      <td>Extended Science Phase</td>
      <td>...</td>
      <td>-11438078.0</td>
      <td>-17117128.0</td>
      <td>-48.5358</td>
      <td>282.545</td>
      <td>-48.5439</td>
      <td>282.423</td>
      <td>-48.3930</td>
      <td>282.401</td>
      <td>-48.3849</td>
      <td>282.522</td>
    </tr>
  </tbody>
</table>
<p>5 rows × 54 columns</p>
</div>

## Instrument tools

### CTX

``` python
from planetarypy.ctx import CTXEDR
```

    Unable to display output for mime type(s): application/javascript, application/vnd.holoviews_load.v0+json

    Unable to display output for mime type(s): application/javascript, application/vnd.holoviews_load.v0+json

<style>.bk-root, .bk-root .bk:before, .bk-root .bk:after {
  font-family: var(--jp-ui-font-size1);
  font-size: var(--jp-ui-font-size1);
  color: var(--jp-ui-font-color1);
}
</style>

``` python
pid = ctrindex.sample(random_state=42).squeeze().PRODUCT_ID
pid
```

    'G01_018691_2639_XN_83N125W'

``` python
ctxedr = CTXEDR(pid)
```

``` python
ctxedr.local_path
```

    Path('/home/ayek72/mnt/slowdata/planetarypy/missions/mro/ctx/edr/G01_018691_2639_XN_83N125W/G01_018691_2639_XN_83N125W.IMG')

``` python
ctxedr
```

    PRODUCT_ID: G01_018691_2639_XN_83N125W
    URL: https://pds-imaging.jpl.nasa.gov/data/mro/mars_reconnaissance_orbiter/ctx/mrox_1189/data/G01_018691_2639_XN_83N125W.IMG
    Local: /home/ayek72/mnt/slowdata/planetarypy/missions/mro/ctx/edr/G01_018691_2639_XN_83N125W/G01_018691_2639_XN_83N125W.IMG
    Shape: (1, 7168, 5056)

``` python
ctxedr.download()
```

    File exists. Use `overwrite=True` to download fresh.

``` python
ctxedr
```

    PRODUCT_ID: G01_018691_2639_XN_83N125W
    URL: https://pds-imaging.jpl.nasa.gov/data/mro/mars_reconnaissance_orbiter/ctx/mrox_1189/data/G01_018691_2639_XN_83N125W.IMG
    Local: /home/ayek72/mnt/slowdata/planetarypy/missions/mro/ctx/edr/G01_018691_2639_XN_83N125W/G01_018691_2639_XN_83N125W.IMG
    Shape: (1, 7168, 5056)
