Unverified Commit eb795cc5 authored by acpaquette's avatar acpaquette Committed by GitHub
Browse files

Kaguyami App and Test Update (#4190)

* Updated kaguyami app to new format

* Updated kaguyami2isis tests and added cropped test data

* Removed old makefile tests

* Updated kaguya cropping notebook to handle bands

* Updated kaguya proj test to fail
parent 74da682d
Loading
Loading
Loading
Loading
+22 −80
Original line number Diff line number Diff line
%% Cell type:code id: tags:

``` python
import pvl
import struct
import matplotlib.pyplot as plt
import numpy as np
import datetime
import os.path
import binascii
```

%% Cell type:code id: tags:

``` python
#kaguya_file = '/scratch/arsanders/kaguyatc/TC2S2B0_01_03043N107E3384.img'
#kaguya_file = '/home/arsanders/testData/apollo/AS15-M-1450.lbl'
kaguya_file = '/home/arsanders/testData/marci/MOI_000009_0294_MU_00N044W.IMG'
kaguya_file = '/Path/to/kaguyami/or/kaguyatc.img'
image_file = kaguya_file
```

%% Cell type:code id: tags:

``` python
header = pvl.load(kaguya_file)
```

%% Cell type:code id: tags:

``` python
header
```

%% Output

    PVLModule([
      ('PDS_VERSION_ID', 'PDS3')
      ('FILE_NAME', 'MOI_000009_0294_MU_00N044W.IMG')
      ('RECORD_TYPE', 'FIXED_LENGTH')
      ('RECORD_BYTES', 128)
      ('FILE_RECORDS', 2259)
      ('LABEL_RECORDS', 11)
      ('^IMAGE', 12)
      ('SPACECRAFT_NAME', 'MARS_RECONNAISSANCE_ORBITER')
      ('INSTRUMENT_NAME', 'MARS COLOR IMAGER')
      ('INSTRUMENT_HOST_NAME', 'MARS RECONNAISSANCE ORBITER')
      ('MISSION_PHASE_NAME', 'POSTMOI')
      ('TARGET_NAME', 'MARS')
      ('INSTRUMENT_ID', 'MARCI')
      ('PRODUCER_ID', 'MRO_MARCI_TEAM')
      ('DATA_SET_ID', 'MRO-M-MARCI-2-EDR-L0-V1.0')
      ('PRODUCT_CREATION_TIME',
       datetime.datetime(2007, 5, 17, 18, 31, 28, tzinfo=datetime.timezone.utc))
      ('SOFTWARE_NAME', 'makepds05 $Revision: 1.7 $')
      ('UPLOAD_ID', 'UNK')
      ('ORIGINAL_PRODUCT_ID', '4A_05_0001000200')
      ('PRODUCT_ID', 'MOI_000009_0294_MU_00N044W')
      ('START_TIME',
       datetime.datetime(2006, 3, 24, 4, 25, 53, 96000, tzinfo=datetime.timezone.utc))
      ('STOP_TIME',
       datetime.datetime(2006, 3, 24, 4, 55, 48, 296000, tzinfo=datetime.timezone.utc))
      ('SPACECRAFT_CLOCK_START_COUNT', '827641567:30')
      ('SPACECRAFT_CLOCK_STOP_COUNT', 'N/A')
      ('INTERFRAME_DELAY', Quantity(value=3.2, units='SECONDS'))
      ('FOCAL_PLANE_TEMPERATURE', Quantity(value=240.9, units='K'))
      ('SAMPLE_BIT_MODE_ID', 'SQROOT')
      ('LINE_EXPOSURE_DURATION', Quantity(value=3112.237, units='MSEC'))
      ('SAMPLING_FACTOR', 8)
      ('SAMPLE_FIRST_PIXEL', 0)
      ('FILTER_NAME', frozenset({'LONG_UV', 'SHORT_UV'}))
      ('RATIONALE_DESC', 'Post-MOI image of Argyre and Mare Erythraeum region')
      ('DATA_QUALITY_DESC', 'OK')
      ('ORBIT_NUMBER', 9)
      ('IMAGE',
       {'CHECKSUM': 12820826,
        'LINES': 2248,
        'LINE_PREFIX_BYTES': 0,
        'LINE_SAMPLES': 128,
        'LINE_SUFFIX_BYTES': 0,
        'SAMPLE_BITS': 8,
        'SAMPLE_BIT_MASK': 255,
        'SAMPLE_TYPE': 'UNSIGNED_INTEGER'})
    ])

%% Cell type:code id: tags:

``` python
header["^IMAGE"]
```

%% Output

    12

%% Cell type:code id: tags:

``` python
with open(kaguya_file, 'rb') as f:
    try:
        # For marci image
        image_offset = header['^IMAGE'] * header['LABEL_RECORDS'] * header["RECORD_BYTES"] - (header['IMAGE']['SAMPLE_BITS']//8)
        # image_offset = header['^IMAGE'] * header['LABEL_RECORDS'] * header["RECORD_BYTES"] - (header['IMAGE']['SAMPLE_BITS']//8)

        # For others
        # image_offset = header["^IMAGE"].value-(header['IMAGE']['SAMPLE_BITS']//8)
        image_offset = header["^IMAGE"].value-(header['IMAGE']['SAMPLE_BITS']//8)

        f.seek(image_offset)
        b_image_data = f.read()
    except AttributeError:
        # If detached label, "^IMAGE" will be a list.
        image_file = os.path.dirname(kaguya_file) + "/" + header["^IMAGE"][0]
        image_offset = header["^IMAGE"][1].value
        with open(image_file, 'rb') as im_f:
            b_image_data = im_f.read()
```

%% Cell type:code id: tags:

``` python
n_lines = 40
n_lines = 20
n_bands = 2
if "BANDS" not in header["IMAGE"].keys():
    n_bands = 1
line_length = header['IMAGE']['LINE_SAMPLES'] * (header['IMAGE']['SAMPLE_BITS']//8)
```

%% Cell type:code id: tags:

``` python
image_data = []
for j in range(n_lines):
    image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length], dtype=np.int16, count=int(line_length/2))
    image_data.append(image_sample)
for i in range(n_bands):
    image_data.append([])
    for j in range(n_lines):
        image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length], dtype=np.int16, count=int(line_length/2))
        image_data[i].append(image_sample)
image_data = np.array(image_data)
```

%% Cell type:code id: tags:

``` python
image_data.shape
image_data.min()
```

%% Output

    (40, 64)

%% Cell type:code id: tags:

``` python
plt.imshow(image_data)
plt.imshow(image_data[0])
```

%% Output

    <matplotlib.image.AxesImage at 0x10ec70fd0>


%% Cell type:code id: tags:

``` python
class RealIsisCubeLabelEncoder(pvl.encoder.ISISEncoder):
    def encode_time(self, value):
        if value.microsecond:
            second = u'%02d.%06d' % (value.second, value.microsecond)
        else:
            second = u'%02d' % value.second

        time = u'%02d:%02d:%s' % (value.hour, value.minute, second)
        return time
```

%% Cell type:code id: tags:

``` python
image_fn, image_ext = os.path.splitext(image_file)
crop = '_cropped'
mini_image_fn = image_fn + crop + image_ext
mini_image_bn = os.path.basename(mini_image_fn)

grammar = pvl.grammar.ISISGrammar()
grammar.comments+=(("#", "\n"), )
encoder = RealIsisCubeLabelEncoder()

# Overwrite the number of lines in the label
header['IMAGE']['LINES'] = n_lines
header['IMAGE']['BANDS'] = n_bands

if kaguya_file != image_file:
    # If detached label, point the mini label to the mini image
    header['^IMAGE'] = [mini_image_bn, pvlcollections.Units(1, 'BYTES')]
    header['FILE_NAME'] = mini_image_bn
else:
    # If attached label, calculate the new offset
    header['^IMAGE'] = pvl.collections.Units(len(pvl.dumps(header, encoder=encoder, grammar=grammar)), 'BYTES')
```

%% Cell type:code id: tags:

``` python
label_fn, label_ext = os.path.splitext(kaguya_file)
out_label = label_fn + crop + label_ext
print(out_label)

pvl.dump(header, out_label, encoder=encoder, grammar=grammar)
```

%% Output

    1820

%% Cell type:code id: tags:

``` python
with open(mini_image_fn, 'ab+') as f:
    b_reduced_image_data = image_data.tobytes()
    f.seek(0, 2)
    f.write(b_reduced_image_data)
```

%% Cell type:code id: tags:

``` python
pvl.load(mini_image_fn)
```

%% Cell type:code id: tags:

``` python
```
+159 −0
Original line number Diff line number Diff line
#include "kaguyami2isis.h"

#include <cstdio>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

#include "ProcessImportPds.h"
#include "ProgramLauncher.h"

#include "UserInterface.h"
#include "FileName.h"
#include "IString.h"

using namespace std;

static double range(double x);

namespace Isis {

  void kaguyami2isis(UserInterface &ui) {
    ProcessImportPds p;
    Pvl label;

    FileName inFile = ui.GetFileName("FROM");
    QString id;
    Pvl lab(inFile.expanded());

    if (lab.hasObject("IMAGE_MAP_PROJECTION")) {
      QString msg = "Unsupported projected file [" + inFile.expanded() + "]";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    try {
      id = (QString) lab.findKeyword("DATA_SET_ID");
    }
    catch(IException &e) {
      QString msg = "Unable to read [DATA_SET_ID] from input file [" +
                    inFile.expanded() + "]";
      throw IException(e, IException::Unknown, msg, _FILEINFO_);
    }

    p.SetPdsFile(inFile.expanded(), "", label);
    CubeAttributeOutput &att = ui.GetOutputAttribute("TO");
    Cube *outcube = p.SetOutputCube(ui.GetFileName("TO"), att);

    // Get user entered special pixel ranges
    if(ui.GetBoolean("SETNULLRANGE")) {
      p.SetNull(ui.GetDouble("NULLMIN"), ui.GetDouble("NULLMAX"));
    }
    if(ui.GetBoolean("SETHRSRANGE")) {
      p.SetHRS(ui.GetDouble("HRSMIN"), ui.GetDouble("HRSMAX"));
    }
    if(ui.GetBoolean("SETHISRANGE")) {
      p.SetHIS(ui.GetDouble("HISMIN"), ui.GetDouble("HISMAX"));
    }
    if(ui.GetBoolean("SETLRSRANGE")) {
      p.SetLRS(ui.GetDouble("LRSMIN"), ui.GetDouble("LRSMAX"));
    }
    if(ui.GetBoolean("SETLISRANGE")) {
      p.SetLIS(ui.GetDouble("LISMIN"), ui.GetDouble("LISMAX"));
    }

    p.SetOrganization(Isis::ProcessImport::BSQ);

    p.StartProcess();

    // Get the directory where the Kaguya MI translation tables are.
    QString transDir = "$ISISROOT/appdata/translations/";
    Pvl inputLabel(inFile.expanded());
    Pvl *outputLabel = outcube->label();
    FileName transFile;

    // Translate the Archive group
    transFile = transDir + "KaguyaMiArchive.trn";
    PvlToPvlTranslationManager archiveXlater(inputLabel, transFile.expanded());
    archiveXlater.Auto(*(outputLabel));

    // Translate the Instrument group
    transFile = transDir + "KaguyaMiInstrument.trn";
    PvlToPvlTranslationManager instrumentXlater(inputLabel, transFile.expanded());
    instrumentXlater.Auto(*(outputLabel));
      //trim trailing z's from the time strings
    PvlGroup &instGroup(outputLabel->findGroup("Instrument",Pvl::Traverse));
    QString timeString;
      //StartTime
    PvlKeyword &startTimeKeyword=instGroup["StartTime"];
    timeString = startTimeKeyword[0];
    startTimeKeyword.setValue( timeString.mid(0,timeString.lastIndexOf("Z")) );
      //StartTimeRaw
    PvlKeyword &startTimeRawKeyword=instGroup["StartTimeRaw"];
    timeString = startTimeRawKeyword[0];
    startTimeRawKeyword.setValue( timeString.mid(0,timeString.lastIndexOf("Z")) );
      //StopTime
    PvlKeyword &stopTimeKeyword=instGroup["StopTime"];
    timeString = stopTimeKeyword[0];
    stopTimeKeyword.setValue( timeString.mid(0,timeString.lastIndexOf("Z")) );
      //StopTimeRaw
    PvlKeyword &stopTimeRawKeyword=instGroup["StopTimeRaw"];
    timeString = stopTimeRawKeyword[0];
    stopTimeRawKeyword.setValue( timeString.mid(0,timeString.lastIndexOf("Z")) );


    // Translate the BandBin group
    transFile = transDir + "KaguyaMiBandBin.trn";
    PvlToPvlTranslationManager bandBinXlater(inputLabel, transFile.expanded());
    bandBinXlater.Auto(*(outputLabel));

    //Set up the Kernels group
    PvlGroup kern("Kernels");
    QString baseBand = lab.findKeyword("BASE_BAND")[0];
    if (lab.findKeyword("INSTRUMENT_ID")[0] == "MI-VIS") {
      if (baseBand.contains("MV")) {
        kern += PvlKeyword("NaifFrameCode", toString(-13133) + baseBand[2]);
      }
      kern += PvlKeyword("NaifCkCode", toString(-131330));
    }
    else if (lab.findKeyword("INSTRUMENT_ID")[0] == "MI-NIR") {
      if (baseBand.contains("MN")) {
        kern += PvlKeyword("NaifFrameCode", toString(-13134) + baseBand[2]);
      }
      kern += PvlKeyword("NaifCkCode", toString(-131340));
    }

    //At the time of this writing there was no expectation that Kaguya ever did any binning
    //  so this is check to make sure an error is thrown if an image was binned
    if (lab.findKeyword("INSTRUMENT_ID")[0] == "MI-VIS" && outcube->sampleCount() != 962 ) {
      QString msg = "Input file [" + inFile.expanded() + "]" + " appears to be binned.  Binning was "
                    "unexpected, and is unsupported by the camera model";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }
    if (lab.findKeyword("INSTRUMENT_ID")[0] == "MI-NIR" && outcube->sampleCount() != 320 ) {
      QString msg = "Input file [" + inFile.expanded() + "]" + " appears to be binned.  Binning was "
                    "unexpected, and is unsupported by the camera model";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }

    outcube->putGroup(kern);

    p.EndProcess();
  }

  double range(double x) {
    double a,b,c;
    b = x / 360;
    if(b > 0) {
      c = floor(b);
    }
    else {
      c = ceil(b);
    }
    a = 360 * (b - c);
    if(a < 0) {
      a = a + 360;
    }
    return a;
  }
}
+10 −0
Original line number Diff line number Diff line
#ifndef kaguyami2isis_h
#define kaguyami2isis_h

#include "UserInterface.h"

namespace Isis {
  extern void kaguyami2isis(UserInterface &ui);
}

#endif
+4 −167

File changed.

Preview size limit exceeded, changes collapsed.

+0 −4
Original line number Diff line number Diff line
BLANKS = "%-6s"    
LENGTH = "%-40s"

include $(ISISROOT)/make/isismake.tststree
Loading