"After downloading image data, it is necessary to convert the image to ISIS cube format and spiceinit the data. The following command will convert and spiceinit an LRO NAC image, but the specific \"2isis\" command is mission-specific. Unlike other code segments in this notebook, these commands should be run in a terminal.\n",
"\n",
"<div class=\"admonition warning\">\n",
" <p class=\"admonition-title\">Create the Truth Data with ISIS!</p>\n",
" <p> This cub file will be used as truth data, so it should be spiceinitted using ISIS camera models rather than the ALE driver. You should <em>deactivate</em> your ALE environment when spiceinitting this cube!\n",
Before merging a new driver into ALE, it is necessary to create automated tests to ensure that the driver functions properly. Writing a test for ALE drivers entails two separate stages -- preparing the test data and writing the test itself.
<divclass="admonition info">
<pclass="admonition-title">Prerequisites</p>
<p>This tutorial assumes that the user has:
<list>
<li>an active conda environment with ALE and its dependencies</li>
<li>base and mission-specific SPICE data (camera kernels)</li>
<li>access to ISIS applications (spiceinit)</li>
</list>
</p>
</div>
## Prepare Test Data
Naturally, ALE drivers require instrument-specific data. If you have not yet identified a source of test data for your driver, the [PDS Image Atlas](https://pds.nasa.gov/datasearch/data-search/) provides a catalog of data from which you can select relevant images.
The data used in this tutorial can be found [here](https://wms.lroc.asu.edu/lroc/view_lroc/LRO-L-LROC-2-EDR-V1.0/M1435111335LE)
### Create and Spiceinit a Cube
After downloading image data, it is necessary to convert the image to ISIS cube format and spiceinit the data. The following command will convert and spiceinit an LRO NAC image, but the specific "2isis" command is mission-specific. Unlike other code segments in this notebook, these commands should be run in a terminal.
<divclass="admonition warning">
<pclass="admonition-title">Create the Truth Data with ISIS!</p>
<p> This cub file will be used as truth data, so it should be spiceinitted using ISIS camera models rather than the ALE driver. You should <em>deactivate</em> your ALE environment when spiceinitting this cube!
After creating the ISIS formatted cube, it is necessary to pull the label off the cube. This is easily performed using ISIS's `catlab` utility via the command line:
Due to repository size limitations, it is necessary to 'slice' the kernels with *ckslicer*, which is a NAIF utility that can be downloaded [here](https://naif.jpl.nasa.gov/naif/utilities.html). Make sure that you download the utility that corresponds to your operating system and remember where you downloaded the program.
#### Import and Set Up Data Locations
This portion of the code is responsible for loading the libraries necessary for slicing and merging kernels. It's not necessary to alter any of the imports, but be sure to edit the cube locations so that they correspond to your directory structure and create the output_dir if necessary!
%% Cell type:code id:333c6885 tags:
``` python
importspiceypyasspice
importpvl
importos
importre
importsubprocess
fromaleimportutil
fromitertoolsimportchain
importio
importnetworkxasnx
# These should be provided when running this script.
cube="M1435111335LE.cub"
output_dir="kernels/"# Output dir for created kernel files
data_dir="/Users/arsanders/isis_efs/isis_data/"# Dir of where to pull original kernels from
```
%% Cell type:markdown id:19895955 tags:
#### Create Utility Functions
Next, it is necessary to create utility functions to merge intervals together and add light-time correction. There is generally no need to adjust these functions, but it is necessary to load them into memory -- just run this cell!
%% Cell type:code id:6e3638b5 tags:
``` python
defmerge_intervals(intervals):
"""
Merge a set of intervals. The intervals are assumed to be closed, that is they include the end-points.
Parameters
----------
intervals : list
The input list of intrvals where each interval is a tuple of (start, end)
This section of the code is responsible for reading the list of kernels from a spiceinit'd cube and loading those kernels into memory. No edits are necessary to this portion of the notebook.
This portion of the code is responsible for reading the .cub label and updating the dictionary with information relevant to the upcoming kernel slicing process.
In some circumstances, it may be necessary to update the lowest-level dictionary elements to match those found in your cube's label, i.e. "SpacecraftClockStartCount" or "Line Exposure Duration" may not be present in your label. It may also be necessary to add (or remove) a list index if your value contains a unit specifier. For example, the "LineExposureDuration" keyword specifies units, so we have to add the [0] to pull the value out of the tuple. If your LineExposureDuration does not contain units, simply remove the [0].
After collecting the necessary metadata, it is possible to 'slice' out the portions of kernels that are relevant to your specific image. The following code will slice the kernels and convert them to transfer format. This cell may require the user to specify the full path to the ckslicer executable. Alternatively, the user can place the utility in the same directory as the notebook.
%% Cell type:code id:0f65c42d tags:
``` python
# Account for light time correction
intervals=add_light_time_correction(cube_info)
# For each binary ck kernel specified in cube, run the ckslicer, comment and to-transfer commands
ALE provides the isd_generate.py utility within the 'ale' directory. To use this utility, the user must ensure that the ALESPICEROOT environment variable is set to the data directory containing kernels. This can be achieved using
``` BASH
export ALESPICEROOT=<your_data_directory>
```
After setting ALESPICEROOT, the user can use the python utility to generate an ISD. An example is as follows:
There are numerous data locations and naming conventions that must be followed in order for the tests to function properly. To correctly integrate the test data into ALE's structure, the user should:
- Ensure that your files are named as follows:
- isd: \<instrument_name\>_isd.json
- cube label: \<filename\>_isis3.lbl
- Create a directory within ale/tests/pytests/data that shares a name with your test data
- Place the cube label into the directory that you created
- Place all transfer kernels into the directory that you created (*.xc, *.xsp, *.tls, *.tpc, *.ti, *.tsc)
- Place the isd within the existing ale/tests/pytests/data/isds directory
%% Cell type:markdown id:fa6aefcf tags:
## Writing the Test
ALE uses the PyTest library for automated testing. This section will guide the user through the process of creating a PyTest for an ALE driver using the test data that was generated using the first part of this tutorial.
### Create a Test Fixture
In PyTest, a test [fixture](https://docs.pytest.org/en/6.2.x/fixture.html) is an object that models test data, and it includes all the data, setup, and teardown instructions that are necessary to perform automated tests. The following cell demonstrates a test fixture that provides all the necessary test data for our automated tests.
The first test that a driver needs to pass is whether or not it is able to parse a label as expected. The following cell performs the parsing, loading, and comparison of the ISD to a 'truth' ISD that comes from the ISIS Camera Model.
After verifying that the driver passes the 'loads' test, it is necessary to test each function within the driver. For this portion of testing, it is necessary to test any function that your driver overrides. In general, this step involves testing that the driver's method returns the expected value from the cube label.
<divclass="admonition note">
<pclass="admonition-title">Notes on 'patch'</p>
<p>The unittest library provides a means of mocking objects using 'patch'. All spice calls are mocked using this process.For more information on the use of 'patch,' visit the unittest <ahref=https://docs.python.org/3/library/unittest.mock.html>documentation</a>.</p>
</div>
%% Cell type:code id:eb129f6d tags:
``` python
# ========= Test isislabel and naifspice driver =========