Commit 9ea482aa authored by Summer Stapleton's avatar Summer Stapleton Committed by Jesse Mapel
Browse files

Making changes to KernelSlice notebook as per reviewer requests (#257)

* Making changes to KernelSlice notebook as per reviewer requests

* Forgot to finish a comment

* Removing commented-out lines as per reviewer request
parent d6740b6a
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
%% Cell type:code id: tags:

``` python
import spiceypy as spice
import pvl
import os
import re
import subprocess
from ale import util
from itertools import chain
import io
import networkx as nx
import tempfile


# These should be provided when running this script.
cube = "/work/users/sgstapleton/kernel_split/EN1072174528M.cub"
output_dir = "/work/users/sgstapleton/kernel_split/" # Output dir for created kernel files
data_dir = "/usgs/cpkgs/isis3/data/" # Dir of where to pull original kernels from
ckslicer_loc = "/work/users/sgstapleton/kernel_split/ckslicer"


def get_reference_id(bc_filename):
    brief = subprocess.check_output(["ckbrief", bc_filename])
    reference = None

    for line in brief.splitlines():
        line = str(line)
        if('Object:' in line):
            reference = int(line.strip("''").split()[1])

    return reference


def add_light_time_correction(cube_info, kernels):

    furnished_kerns = spice.furnsh(kernels)
def add_light_time_correction(cube_info):

    image_start_et = spice.scs2e(cube_info['SpacecraftID'], cube_info['SpacecraftClockCount'])
    image_end_et = image_start_et + cube_info['ExposureDuration']

    inst_state, inst_lt = spice.spkez(cube_info['SpacecraftID'], (image_start_et + image_end_et)/2, 'J2000', 'LT+S', 0)
    target_state, target_lt = spice.spkez(cube_info['TargetID'], (image_start_et + image_end_et)/2, 'J2000', 'LT+S', 0)

    lt_pad = max(abs(inst_lt), abs(target_lt)) + 15

    # Eph time
    padded_start_et = image_start_et - lt_pad
    padded_end_et = image_end_et + lt_pad

    # Padded times
    padded_start_sclk = spice.sce2s(cube_info['SpacecraftID'], padded_start_et)
    padded_end_sclk = spice.sce2s(cube_info['SpacecraftID'], padded_end_et)
    padded_start_utc = spice.et2utc(padded_start_et, 'c', 3)
    padded_end_utc = spice.et2utc(padded_end_et, 'c', 3)

    cube_info.update(PaddedStartTimeSCLK = padded_start_sclk)
    cube_info.update(PaddedEndTimeSCLK = padded_end_sclk)
    cube_info.update(PaddedStartTimeUTC = padded_start_utc)
    cube_info.update(PaddedEndTimeUTC = padded_end_utc)


def get_body_ids(spk_file, body_id):
    brief = subprocess.check_output(["brief", "-c {}".format(spk_file)])

    # Convert from bytes
    brief = brief.decode("utf-8")
    brief_io = io.StringIO(brief)
    line = brief_io.readline()
    edge_list = []

    while(line):

        if("w.r.t" in line):
                bodies_results = re.findall('\((.*?)\)', line)
                edge_list.append(bodies_results)

        line = brief_io.readline()

    G = nx.DiGraph()
    G.add_edges_from(edge_list)

    body_ids = []
    for path in nx.all_simple_paths(G, body_id, '0'):
        body_ids = body_ids + path

    body_ids = set(body_ids)

    return body_ids


def output_spkmerge_config(config_file, cube_info, output_dir):

    with open(config_file, "w+") as config:
        config.write('''LEAPSECONDS_KERNEL     = {}\n'''.format(cube_info['LeapSecond'][0]))

        for kern in cube_info['InstrumentPosition']:

            basename = os.path.basename(kern).split('.')[0]
            filename, file_extension = os.path.splitext(kern)
            new_kern = output_dir + basename + "_merged" + file_extension

            config.write('''      SPK_KERNEL             = {}\n'''.format(new_kern))

            body_ids = get_body_ids(kern, str(cube_info['SpacecraftID']))

            for body in body_ids:

                if body != '0':

                    config.write('''         SOURCE_SPK_KERNEL   = {}\n'''.format(kern))
                    config.write('''            INCLUDE_COMMENTS = no\n''')
                    config.write('''            BODIES              = {}\n'''.format(body))
                    config.write('''            BEGIN_TIME          = {}\n'''.format(cube_info['PaddedStartTimeUTC']))
                    config.write('''            END_TIME            = {}\n'''.format(cube_info['PaddedEndTimeUTC']))

    config.close()

```

%% Cell type:code id: tags:

``` python
# These are the processing steps. This will make use of the cube provided further up to create smaller,
# more manageable kernel files for ale testing purposes. This currently only handles ck and spk files.

# Get dictionary of kernel lists from cube
cube_info = util.generate_kernels_from_cube(cube, 'dict')
cube_info = util.generate_kernels_from_cube(cube, format_as = 'dict')

# Replace path variables with absolute paths for kernels
for kernel_list in cube_info:
    for index, kern in enumerate(cube_info[kernel_list]):
        if kern is not None:
            cube_info[kernel_list][index] = data_dir + kern.strip('$')

# Create ordered list of kernels for furnishing
kernels = [kernel for kernel in chain.from_iterable(cube_info.values()) if isinstance(kernel, str)]
spice.furnsh(kernels)

# Loads cube as pvl to extract rest of data
cube_pvl = pvl.load(cube)

# Save other necesary info in cube_info dict
cube_info.update(SpacecraftClockCount = cube_pvl['IsisCube']['Instrument']['SpacecraftClockCount'])
cube_info.update(ExposureDuration = cube_pvl['IsisCube']['Instrument']['ExposureDuration'].value * 0.001)
cube_info.update(TargetID = spice.bods2c(cube_pvl['IsisCube']['Instrument']['TargetName']))
cube_info.update(SpacecraftID = spice.bods2c(cube_pvl['IsisCube']['Instrument']['SpacecraftName']))

# Add lighttime-corrected SCLK values to cube_info
add_light_time_correction(cube_info, kernels)
add_light_time_correction(cube_info)

# For each binary ck kernel specified in cube, run the ckslicer, comment and to-transfer commands
for ck in cube_info['InstrumentPointing']:
    if ck.endswith('.bc'):

        # Get reference id associated with ck
        reference_id = get_reference_id(ck)

        ck_filename = os.path.basename(ck).split('.')[0]
        ck_path, ck_file_extension = os.path.splitext(ck)
        output_kern = output_dir + ck_filename + '_sliced' + ck_file_extension

        # Create new sliced ck kernel
        ckslicer_command = ["./ckslicer",
        ckslicer_command = [ckslicer_loc,
                                '-LSK {}'.format(cube_info['LeapSecond'][0]),
                                '-SCLK {}'.format(cube_info['SpacecraftClock'][0]),
                                '-INPUTCK {}'.format(ck),
                                '-OUTPUTCK {}'.format(output_kern),
                                '-ID {}'.format(reference_id),
                                '-TIMETYPE {}'.format('SCLK'),
                                '-START {}'.format(cube_info['PaddedStartTimeSCLK']),
                                '-STOP {}'.format(cube_info['PaddedEndTimeSCLK'])]
        subprocess.call(ckslicer_command)

        # Remove old comments from new ck kernel
        commnt_command = ['commnt', '-d {}'.format(output_kern)]
        subprocess.call(commnt_command)

        # Makes a new txt file for the only comments that should be stored in the new ck file
        with open("temp_commnts.txt","w+") as f:
        with open(output_dir + "temp_commnts.txt","w+") as f:
            f.write("This CK is for testing with the image: {}\n".format(cube))
            f.write("\nThis CK was generated using the following command: {}\n".format(" ".join(ckslicer_command)))

        # Add new comments to new ck kernel
        new_commnts_command = ["commnt", "-a {}".format(output_kern), "temp_commnts.txt"]
        subprocess.call(new_commnts_command)

        # Clean up temp comment file
        os.remove(output_dir + "temp_commnts.txt")

        # Create the transfer file of the new ck kernel
        subprocess.call(["toxfr", output_kern])

# Create the config file for the spkmerge command
output_spkmerge_config(output_dir + "spk.config", cube_info, output_dir)

# Run the spkmerge command
spkmerge_command = ["spkmerge", output_dir + "spk.config"]
subprocess.call(spkmerge_command)

# Clean up temp config file
os.remove(output_dir + "spk.config")
```

%% Cell type:code id: tags:

``` python
```