From a59a95194b6b61d6c2593a88208322ec6052b2cd Mon Sep 17 00:00:00 2001 From: Tyler Wilson Date: Fri, 14 Dec 2018 15:01:35 -0700 Subject: [PATCH 01/24] Added AlphaCube group to outputlabel in the event the image is cropped. --- isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp index e9f016be61..944f24a3fd 100644 --- a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp @@ -3,6 +3,7 @@ #include #include +#include "AlphaCube.h" #include "FileName.h" #include "iTime.h" #include "OriginalLabel.h" @@ -12,6 +13,7 @@ #include "PvlKeyword.h" #include "PvlObject.h" #include "PvlToPvlTranslationManager.h" + #include "UserInterface.h" using namespace std; @@ -34,6 +36,11 @@ void IsisMain () { // Create a PVL to store the translated labels in Pvl outputLabel; + //Uncropped # of samples/lines + int N = 1024; + int Nsl = 1; + + // Get the FITS label Pvl fitsLabel; fitsLabel.addGroup(importFits.fitsImageLabel(0)); @@ -46,7 +53,7 @@ void IsisMain () { throw IException(e, IException::Unknown, msg, _FILEINFO_); } - + fitsLabel.write(FileName(ui.GetFileName("FROM")).expanded()+"fit.txt"); QString instid; QString missid; @@ -89,7 +96,6 @@ void IsisMain () { if (formatType.contains("2a") || formatType.contains("2b")) distortionCorrection = false; - missid = missid.simplified().trimmed(); if (QString::compare(missid, "HAYABUSA-2", Qt::CaseInsensitive) != 0) { QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() + @@ -118,6 +124,22 @@ void IsisMain () { PvlGroup &instGrp = outputLabel.findGroup("Instrument",Pvl::Traverse); QString target; + //Check for cropped image + + + int ss = instGrp["SelectedImageAreaX1"]; + int sl = instGrp["SelectedImageAreaY1"]; + int es = instGrp["SelectedImageAreaX2"]; + int el = instGrp["SelectedImageAreaY2"]; + + if (ss > 1 || sl >1 || es < N || el < N) { + + AlphaCube aCube(N, N, outputCube->sampleCount(), outputCube->lineCount(), + ss-0.5, sl - 0.5, es - 0.5, el - 0.5); + aCube.UpdateGroup(*outputCube); + + } + instGrp.addKeyword(PvlKeyword("DistortionCorrection")); try { target = fitsLabel.findGroup("FitsLabels").findKeyword("TARGET")[0]; From c00f88e24efa5d07c6cd76914fed9ebe048402cf Mon Sep 17 00:00:00 2001 From: "B. Seignovert" Date: Mon, 17 Dec 2018 09:18:32 -0800 Subject: [PATCH 02/24] Fix libtiff dependency (#636) (#644) * Upgrade libtiff to 4.0.10 (#636) * Switch libtiff to 4.0.9 or higher to remove geotiff conflict --- environment.yml | 2 +- environment_gcc4.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/environment.yml b/environment.yml index 6aec932d69..ea05a5b363 100644 --- a/environment.yml +++ b/environment.yml @@ -29,7 +29,7 @@ dependencies: - krb5==1.14.2=0 - libpng>=1.6.34 - libprotobuf==3.5.2 - - libtiff==4.0.9=0 + - libtiff>=4.0.9 - libxml2==2.9.7=0 - make - mesalib==17.2.0=0 diff --git a/environment_gcc4.yml b/environment_gcc4.yml index 6a671b8318..9c76350031 100644 --- a/environment_gcc4.yml +++ b/environment_gcc4.yml @@ -30,7 +30,7 @@ dependencies: - krb5==1.14.2=0 - libpng>=1.6.34 - libprotobuf==3.5.2 - - libtiff==4.0.9=0 + - libtiff>=4.0.9 - libxml2==2.9.7=0 - make - mesalib==17.2.0=0 From 645a8388947cbdd6097bd0c21b9d1c3f24a5a993 Mon Sep 17 00:00:00 2001 From: Jesse Mapel Date: Mon, 17 Dec 2018 11:38:31 -0700 Subject: [PATCH 03/24] Moved ISIS3 conda-build recipe from ISIS3_deps repository (#650) --- recipe/build.sh | 5 ++ recipe/meta.yaml | 156 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 recipe/build.sh create mode 100644 recipe/meta.yaml diff --git a/recipe/build.sh b/recipe/build.sh new file mode 100644 index 0000000000..3ace2b9456 --- /dev/null +++ b/recipe/build.sh @@ -0,0 +1,5 @@ +mkdir build +cd build +cmake -GNinja -DJP2KFLAG=ON -Dpybindings=OFF -DCMAKE_INSTALL_PREFIX=$PREFIX -Disis3Data=/usgs/cpkgs/isis3/data -Disis3TestData=/usgs/cpkgs/isis3/testData ../isis +ninja install +ninja docs diff --git a/recipe/meta.yaml b/recipe/meta.yaml new file mode 100644 index 0000000000..06b38780a0 --- /dev/null +++ b/recipe/meta.yaml @@ -0,0 +1,156 @@ +{% set version = "3.6.1" %} +{% set git_branch = "dev" %} +{% set build_number = "0" %} + +package: + name: isis3 + version: {{ version }} + +source: + git_url: 'https://github.com/USGS-Astrogeology/ISIS3.git' + git_branch: {{ git_branch }} + +build: + number: {{ build_number }} + +# Shotgun strat on requirements until we can narrow them down +requirements: + build: + - armadillo==8.200.0=blas_openblas_200 + - blas==1.1=openblas + - bullet==2.86.1=0 + - bz2file==0.98 + - bzip2==1.0.6=1 + - cmake=>3.10 + - cspice==66=h470a237_3 + - curl==7.60.0=0 + - doxygen==1.8.14=0 + - eigen==3.3.3=0 + - embree==2.14.0=0 + - geos==3.5.1 + - geotiff==1.4.2=1 + - gmm==5.0 + - gmp==6.1.2=0 + - gsl==2.2.1=blas_openblas_3 + - hdf5==1.8.18=2 + - icu==58.2=0 + - jama==125 + - jpeg==9b=2 + - kakadu==1 + - krb5==1.14.2=0 + - libpng>=1.6.34 + - libprotobuf==3.5.2 + - libtiff=>4.0.9 + - libxml2==2.9.7=0 + - make + - mesalib==17.2.0=0 + - mysql==5.7.20 + - mysql-connector-c==6.1.6=0 + - nanoflann==1.2.2 + - ninja==1.7.2=0 + - nn + # - numpy==1.13.3=py36_blas_openblas_200 + - openblas==0.2.19=2 + - opencv==3.2.0|3.3.0 + - openssl==1.0.2n=0 + - patchelf==0.9 + - pcl==1.8.1 + - pip==9.0.1 + - protobuf==3.5.2 + # - pyqt==5.6.0 + - python==3.6 + - qhull==7.2.0=0 + - qt=5.9.6 + - qwt=6.1.3 + - setuptools=38.5.1 + - sip==4.18 + - sqlite==3.13.0=1 + - suitesparse==4.5.4=blas_openblas_200 + - superlu==5.2.1=blas_openblas_201 + - tnt==126=0 + - wheel==0.30.0 + - x264==20131218 + - xalan-c==1.11 + - xerces-c==3.1.4=0 + - xorg-kbproto==1.0.7=1 + - xorg-libice + - xorg-libsm + - xorg-libx11==1.6.4=6 + - xorg-libxi + - zlib==1.2.11=0 + run: + - armadillo==8.200.0 + - blas==1.1=openblas + - bullet==2.86.1=0 + - bz2file==0.98 + - bzip2==1.0.6=1 + - cmake==3.9.1=0 + - cspice==66=h470a237_3 + - curl==7.60.0=0 + - doxygen==1.8.14=0 + - eigen==3.3.3=0 + - embree==2.14.0=0 + - geos==3.5.1 + - geotiff==1.4.2=1 + - gmm==5.0 + - gmp==6.1.2=0 + - gsl==2.2.1=blas_openblas_3 + - hdf5==1.8.18=2 + - icu==58.2=0 + - jama==125 + - jasper=1 + - jpeg==9b=2 + - kakadu==1 + - krb5==1.14.2=0 + - libpng>=1.6.34 + - libprotobuf==3.5.2 + - libtiff=>4.0.9 + - libxml2==2.9.7=0 + - make + - mesalib==17.2.0=0 + - mysql==5.7.20 + - mysql-connector-c==6.1.6=0 + - nanoflann==1.2.2 + - ninja==1.7.2=0 + - nn + # - numpy==1.13.3=py36_blas_openblas_200 + - openblas==0.2.19=2 + - opencv==3.2.0|3.3.0 + - openssl==1.0.2n=0 + - patchelf==0.9 + - pcl==1.8.1 + - pip==9.0.1 + - protobuf==3.5.2 + # - pyqt==5.6.0 + - python==3.6 + - qhull==7.2.0=0 + - qt=5.9.6 + - qwt=6.1.3 + - setuptools=38.5.1 + - sip==4.18 + - sqlite==3.13.0=1 + - suitesparse==4.5.4=blas_openblas_200 + - superlu==5.2.1=blas_openblas_201 + - tnt==126=0 + - wheel==0.30.0 + - x264==20131218 + - xalan-c==1.11 + - xerces-c==3.1.4=0 + - xorg-kbproto==1.0.7=1 + - xorg-libice + - xorg-libsm + - xorg-libx11==1.6.4=6 + - xorg-libxi + - zlib==1.2.11=0 +# Add the tests eventually +# test: +# + +# about: +# home: https://developers.google.com/protocol-buffers/ +# license: BSD 3-Clause +# license_file: LICENSE +# summary: "Protocol Buffers - Google's data interchange format." + +# extra: +# recipe-maintainers: From 08edafe3bce9f3dbe45c0dd74c2fbebe1d2a7888 Mon Sep 17 00:00:00 2001 From: Jesse Mapel Date: Mon, 17 Dec 2018 14:56:53 -0700 Subject: [PATCH 04/24] Fixed warning in Pixel unit tests --- isis/tests/PixelTests.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/isis/tests/PixelTests.cpp b/isis/tests/PixelTests.cpp index 46ac5b0f7b..308cf7fac0 100644 --- a/isis/tests/PixelTests.cpp +++ b/isis/tests/PixelTests.cpp @@ -2,8 +2,8 @@ #include #include +#include #include -// #include #include #include @@ -465,7 +465,6 @@ TEST(Pixel, static_ToString) { EXPECT_EQ(std::string("Lis"), Pixel::ToString(Isis::Lis)); EXPECT_EQ(std::string("Lrs"), Pixel::ToString(Isis::Lrs)); EXPECT_EQ(std::string("Null"), Pixel::ToString(Isis::Null)); - EXPECT_EQ(std::string("Invalid"), Pixel::ToString(-1.0e+1000)); } TEST(Pixel, ToString) { @@ -477,5 +476,4 @@ TEST(Pixel, ToString) { EXPECT_EQ(std::string("Lis"), Pixel(1,2,3,Isis::Lis).ToString()); EXPECT_EQ(std::string("Lrs"), Pixel(1,2,3,Isis::Lrs).ToString()); EXPECT_EQ(std::string("Null"), Pixel(1,2,3,Isis::Null).ToString()); - EXPECT_EQ(std::string("Invalid"), Pixel(1,2,3,-1.0e+1000).ToString()); } From ca9e66671af0afe17b202896e110e50d6ad991dd Mon Sep 17 00:00:00 2001 From: Tyler Wilson Date: Mon, 17 Dec 2018 16:40:47 -0700 Subject: [PATCH 05/24] Made a tweak to the dimensions of the alpha cube for cropped images to give it the correct dimensions. --- isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp index 944f24a3fd..fe2dadc693 100644 --- a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp @@ -38,7 +38,7 @@ void IsisMain () { //Uncropped # of samples/lines int N = 1024; - int Nsl = 1; + // Get the FITS label @@ -111,7 +111,7 @@ void IsisMain () { // Translate the Instrument group - FileName transFile(transDir + "hyb2oncInstrument.trn"); + FileName transFile(transDir + "hyb2oncInstrument1.trn"); if (updatedKeywords) { transFile = transDir+"hyb2oncInstrumentUpdated.trn"; @@ -135,9 +135,15 @@ void IsisMain () { if (ss > 1 || sl >1 || es < N || el < N) { AlphaCube aCube(N, N, outputCube->sampleCount(), outputCube->lineCount(), - ss-0.5, sl - 0.5, es - 0.5, el - 0.5); + ss-0.5, sl - 0.5, es + 0.5, el + 0.5); aCube.UpdateGroup(*outputCube); + instGrp["SelectedImageAreaX1"] = "1"; + instGrp["SelectedImageAreaY1"] = "1"; + instGrp["SelectedImageAreaX2"] = QString("%1").arg(N); + instGrp["SelectedImageAreaY2"] = QString("%1").arg(N); + + } instGrp.addKeyword(PvlKeyword("DistortionCorrection")); From c3f4513317abcfe8a4e11078f12a3319276cabd7 Mon Sep 17 00:00:00 2001 From: Tyler Wilson Date: Mon, 17 Dec 2018 16:42:13 -0700 Subject: [PATCH 06/24] Changed the transform function so it could process an array of doubles instead of an array of ints. --- .../apps/hyb2onccal/Hyb2OncCalUtils.h | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h index 58290a52d0..abd60f27c9 100644 --- a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h +++ b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "CSVReader.h" @@ -202,6 +203,8 @@ void mat2isis(Mat *matrix, QString cubeName) { } + ocube.close(); + } @@ -215,18 +218,20 @@ void mat2isis(Mat *matrix, QString cubeName) { * @param cubeName The name of the ISIS::Cube that is being created. * */ -void translate(Cube *flatField, int *transform, QString fname) { + +void translate(Cube *flatField,double *transform, QString fname) { + Mat * originalMat = isis2mat(flatField); - int scale = transform[0]; + double scale = transform[0]; - int startsample = transform[1]; - int startline = transform[2]; - int lastsample = transform[3]; - int lastline = transform[4]; + double startsample = transform[1]; + double startline = transform[2]; + double lastsample = transform[3]; + double lastline = transform[4]; - int width = (lastsample-startsample); - int height = (lastline-startline); + double width = (lastsample-startsample); + double height = (lastline-startline); Size sz(flatField->lineCount()/scale,flatField->sampleCount()/scale); @@ -235,10 +240,9 @@ void translate(Cube *flatField, int *transform, QString fname) { Mat temp = *originalMat; - Mat originalCropped = temp(Rect(startsample,startline,width+1,height+1)); - + Mat originalCropped = temp(Rect(startsample,startline,width,height)); - if (scale ==1) { + if (scale ==1) { mat2isis(&originalCropped,fname); } else { @@ -248,6 +252,17 @@ void translate(Cube *flatField, int *transform, QString fname) { } } + + + + + + + + + + + } #endif From d9439fa041d48e5739ade27751fcd9c0882b374c Mon Sep 17 00:00:00 2001 From: Tyler Wilson Date: Mon, 17 Dec 2018 16:43:19 -0700 Subject: [PATCH 07/24] Smear correction was being incorrectly applied to onboard smear corrected images and screwing things up. Fixed it. --- isis/src/hayabusa2/apps/hyb2onccal/main.cpp | 120 +++++++++++--------- 1 file changed, 66 insertions(+), 54 deletions(-) diff --git a/isis/src/hayabusa2/apps/hyb2onccal/main.cpp b/isis/src/hayabusa2/apps/hyb2onccal/main.cpp index 60d5367848..c4dd5a160e 100644 --- a/isis/src/hayabusa2/apps/hyb2onccal/main.cpp +++ b/isis/src/hayabusa2/apps/hyb2onccal/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -57,11 +58,12 @@ struct TemporaryCubeDeleter { enum InstrumentType{ONCW1,ONCW2,ONCT}; -static double g_bitDepth(12); +static int g_bitDepth(12); InstrumentType g_instrument; //For subimage and binning mapping static AlphaCube *alpha(0); +static bool g_cropped(true); static QString g_filter = ""; static QString g_target =""; @@ -199,7 +201,22 @@ void IsisMain() { AlphaCube myAlpha(1024,1024,icube->sampleCount(), icube->lineCount(), startSample,startLine,lastSample,lastLine); - g_bitDepth = inst["BitDepth"]; + try { + g_bitDepth = inst["BitDepth"]; + } + catch (IException &e) { + QString msg = "Unable to read [BitDepth] keyword in the Instrument group " + "from input file [" + icube->fileName() + "]"; + //qDebug() << msg; + g_bitDepth = 12; + + } + + + + if (g_bitDepth < 0) { + g_bitDepth = 12; //Correpsonds to no correction being done for bit depth + } alpha = &myAlpha; @@ -215,6 +232,7 @@ void IsisMain() { try { g_AEtemperature = inst["ONCAETemperature"][0].toDouble(); + qDebug() << "g_AEtemperature: " << g_AEtemperature; } catch(IException &e) { QString msg = "Unable to read [ONCAETemperature] keyword in the Instrument group " @@ -225,6 +243,7 @@ void IsisMain() { try { g_CCD_T_temperature = inst["ONCTCCDTemperature"][0].toDouble(); + qDebug() << "g_CCD_T_Temperature: " << g_CCD_T_temperature; } catch(IException &e) { QString msg = "Unable to read [ONCTCCDTemperature] keyword in the Instrument group " @@ -234,6 +253,7 @@ void IsisMain() { try { g_ECT_T_temperature = inst["ONCTElectricCircuitTemperature"][0].toDouble(); + qDebug() << "g_ECT_T_temperature: " << g_ECT_T_temperature; } catch(IException &e) { QString msg = "Unable to read [ONCTElectricCircuitTemperature] keyword in the Instrument group " @@ -280,14 +300,23 @@ void IsisMain() { // NOTE we do not have a valid flat-field for the W1 or W2 images. FileName flatfile = "NONE"; + PvlGroup alphaCube; + if (g_instrument == InstrumentType::ONCT) { QScopedPointer flatcube; flatfile = DetermineFlatFieldFile(g_filter); - QString reducedFlat(flatfile.expanded()); + try { + alphaCube = icube->group("AlphaCube"); + } + + catch(IException &e) { + g_cropped =false; + } + // Image is not cropped - if (startLine == 1 && startSample == 1) { + if (!g_cropped) { // Determine if we need to subsample the flat field if pixel binning occurred // TODO: test a binned image (add test case). @@ -309,8 +338,8 @@ void IsisMain() { remove(reducedFlat.toLatin1().data()); throw ie; } - QScopedPointer reduced(new Cube(reducedFlat, "r")); - flatcube.swap( reduced ); + //QScopedPointer reduced(new Cube(reducedFlat, "r")); + //flatcube.swap( reduced ); } // Set up processing for flat field as a second input file @@ -318,13 +347,22 @@ void IsisMain() { p.SetInputCube(reducedFlat, att); } else { + // Image is cropped so we have to deal with it FileName transFlat = FileName::createTempFile("$TEMPORARY/" + flatfile.baseName() + "_translated.cub"); Cube *flatOriginal = new Cube(flatfile.expanded() ); - int transform[5] = {binning,startSample,startLine,lastSample,lastLine}; + //int transform[5] = {binning,startSample,startLine,lastSample,lastLine}; + + double alphaStartSample = alphaCube["AlphaStartingSample"][0].toDouble(); + double alphaStartLine = alphaCube["AlphaStartingLine"][0].toDouble(); + double alphaEndSample = alphaCube["AlphaEndingSample"][0].toDouble(); + double alphaEndLine = alphaCube["AlphaEndingLine"][0].toDouble(); + + //int transform[5] = {binning,startSample,startLine,lastSample,lastLine}; + double transform[5] = {(double)binning,alphaStartSample,alphaStartLine,alphaEndSample,alphaEndLine}; // Translates and scales the flatfield image. Scaling // might be necessary in the event that the raw image was also binned. @@ -334,12 +372,15 @@ void IsisMain() { QScopedPointer translated(new Cube(transFlat.expanded(), "r")); flatcube.swap(translated); - CubeAttributeInput att; - std::cout<<" before second setinputcube()...\n"<fileName(); @@ -374,7 +415,7 @@ void IsisMain() { // Calibrate! try { - p.Progress()->SetText("Calibrating Hayabusa2 Cube"); + p.Progress()->SetText("Calibrating Hayabusa2 Cube"); p.StartProcess(Calibrate); } catch (IException &ie) { @@ -404,19 +445,16 @@ void IsisMain() { bnae.addValue(toString(g_bae1, 8)); calibrationLog.addKeyword(bnae); +#if 0 PvlKeyword linearityCoefs("Linearity"); linearityCoefs.addValue(toString(g_L0,8)); linearityCoefs.addValue(toString(g_L1,8)); linearityCoefs.addValue(toString(g_L2,8)); calibrationLog.addKeyword(linearityCoefs); +#endif - static double g_AEtemperature(0.0); - - static double g_CCD_T_temperature(0.0); - static double g_ECT_T_temperature(0.0); - calibrationLog.addKeyword(PvlKeyword("Bias_AETemp", toString(g_AEtemperature, 16))); @@ -438,14 +476,10 @@ void IsisMain() { break; } - - calibrationLog.addKeyword(PvlKeyword("Bias", toString(g_bias, 16), "DN")); calibrationLog.addKeyword(PvlKeyword("Smear_Tvct", toString(g_Tvct, 16))); calibrationLog.addKeyword(PvlKeyword("Smear_texp", toString(g_texp, 16))); - - calibrationLog.addKeyword(PvlKeyword("CalibrationUnits", g_iofCorrection)); calibrationLog.addKeyword(PvlKeyword("RadianceStandard", toString(g_v_standard, 16))); calibrationLog.addKeyword(PvlKeyword("RadianceScaleFactor", toString(g_iofScale, 16))); @@ -596,33 +630,10 @@ void Calibrate(vector& in, vector& out) { return; } - - // TODO: Once smear model and readout time are known, we can add smear correction. - // Compute smear component here as its a constant for the entire sample - // double t1 = g_timeRatio/imageIn.size(); - // double b = binning; - // double c1(1.0); //default if no binning - // - // if (binning > 1) { - // c1 = 1.0/(1.0 + t1*((b -1.0)/(2.0*b) ) ); - // } - // - // double smear = 0; - // for (int j = 0; j < imageIn.size(); j++ ) { - // if ( !IsSpecial(imageIn[j]) ) { - // smear += t1 * ( (imageIn[j] * g_compfactor) - g_bias); - // } - // } - - - - - // Iterate over the line space - for (int i = 0; i < imageIn.size(); i++) { - //qDebug() << "imageIn: " << imageIn[i]; + for (int i = 0; i < imageIn.size(); i++) { imageOut[i] = imageIn[i]*pow(2.0,12-g_bitDepth); - //qDebug() << "imageIOut: " << imageOut[i]; + // Check for special pixel in input image and pass through @@ -635,10 +646,7 @@ void Calibrate(vector& in, vector& out) { imageOut[i] *= g_compfactor; - // 1) BIAS Removal - Only needed if not on-board corrected - // TODO: find image with > 1 subimages - if ( !g_onBoardSmearCorrection ) { @@ -652,6 +660,8 @@ void Calibrate(vector& in, vector& out) { imageOut[i] = imageOut[i] - g_bias; } } + + #if 0 double linearCorrection; linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0); @@ -671,7 +681,8 @@ void Calibrate(vector& in, vector& out) { // if (nsubImages <= 1) { // imageOut[i] = c1*(imageOut[i] - smear); // } - if (g_onBoardSmearCorrection) { + if (!g_onBoardSmearCorrection) { + double smear = 0; for (int j=0;j < imageIn.size();j++) { smear += (imageOut[j]/imageIn.size() ); @@ -698,13 +709,14 @@ void Calibrate(vector& in, vector& out) { // If we have only one input cube, that means that we do not have a flat-field (W1/W2). if (in.size() == 2) { // Note that our current flat-fields to not have special pixel values. - if ( IsSpecial(flatField[i]) ) { + if ( IsSpecial(flatField[i]) || IsSpecial(imageOut[i]) ) + { imageOut[i] = Isis::Null; continue; } else { - if (flatField[i] != 0) { - imageOut[i] /= flatField[i]; + if (flatField[i] != 0) { + imageOut[i] /= flatField[i]; } } } From 23978de96a2c6663b9eee52c635a7817b9881bf8 Mon Sep 17 00:00:00 2001 From: Tyler Wilson Date: Tue, 18 Dec 2018 16:33:20 -0700 Subject: [PATCH 08/24] Added gtest capability to hyb2onc2isis --- .../apps/hyb2onc2isis/hyb2onc2isis.cpp | 262 ++++++++++++++++++ .../apps/hyb2onc2isis/hyb2onc2isis.h | 17 ++ isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp | 227 +-------------- isis/tests/hyb2onc2isisTests.cpp | 22 ++ 4 files changed, 303 insertions(+), 225 deletions(-) create mode 100644 isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp create mode 100644 isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h create mode 100644 isis/tests/hyb2onc2isisTests.cpp diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp new file mode 100644 index 0000000000..b76d1cd09c --- /dev/null +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp @@ -0,0 +1,262 @@ +#include "hyb2onc2isis.h" + +#include "AlphaCube.h" +#include "Application.h" +#include "FileName.h" +#include "iTime.h" +#include "OriginalLabel.h" +#include "ProcessImportFits.h" +#include "Pvl.h" +#include "PvlGroup.h" +#include "PvlKeyword.h" +#include "PvlObject.h" +#include "PvlToPvlTranslationManager.h" + +#include "UserInterface.h" + +#include +#include + + +using namespace std; +using namespace Isis; +namespace Isis { + + +void hyb2onc2isis(UserInterface &ui) { + + ProcessImportFits importFits; + + QString fitsFileName = FileName(ui.GetFileName("FROM")).expanded(); + QString outputCubeFileName = FileName(ui.GetFileName("TO")).expanded(); + + QString target(""); + if (ui.WasEntered("TARGET")) { + target = ui.GetString("TARGET"); + } + + // Create a PVL to store the translated labels in + Pvl * outputLabel = hyb2onc2isis(fitsFileName,outputCubeFileName,target); + + return; + + } + + +Pvl * hyb2onc2isis(QString &fitsFileName, QString &outputCubeFileName, QString target) { + + ProcessImportFits importFits; + importFits.setFitsFile(FileName(fitsFileName)); + importFits.setProcessFileStructure(0); + bool updatedKeywords = true; + bool distortionCorrection = true; + Cube *outputCube = importFits.SetOutputCube(outputCubeFileName); + + // Get the directory where the Hayabusa translation tables are. + PvlGroup dataDir (Preference::Preferences().findGroup("DataDirectory")); + QString transDir = (QString) dataDir["Hayabusa2"] + "/translations/"; + + // Create a PVL to store the translated labels in + Pvl outputLabel; + + //Uncropped # of samples/lines + int N = 1024; + + // Get the FITS label + Pvl fitsLabel; + fitsLabel.addGroup(importFits.fitsImageLabel(0)); + try { + fitsLabel.addGroup(importFits.extraFitsLabel(0)); + } + catch (IException &e) { + QString msg = "Input file [" + fitsFileName + + "] does not appear to be a Hayabusa2/ONC label file."; + throw IException(e, IException::Unknown, msg, _FILEINFO_); + } + + + QString instid; + QString missid; + QString naifid; + QString formatType; + + try { + instid = fitsLabel.findGroup("FitsLabels").findKeyword("INSTRUME")[0]; + missid = fitsLabel.findGroup("FitsLabels").findKeyword ("SPCECRFT")[0]; + } + catch (IException &e) { + QString msg = "Unable to read instrument ID, [INSTRUME], or spacecraft ID, [SPCECRFT], " + "from input file [" + fitsFileName + "]"; + throw IException(e, IException::Io,msg, _FILEINFO_); + } + try { + naifid = fitsLabel.findGroup("FitsLabels").findKeyword("NAIFID")[0]; + } + catch(IException &e) { + updatedKeywords=false; + } + + try { + formatType = fitsLabel.findGroup("FitsLabels").findKeyword("EXTNAME")[0]; + } + catch(IException &e) { + QString msg = "Unable to read EXTNAME from input file [" + +fitsFileName + "]"; + throw IException(e, IException::Io,msg, _FILEINFO_); + } + + try { + naifid = fitsLabel.findGroup("FitsLabels").findKeyword("NAIFID")[0]; + } + catch(IException &e) { + updatedKeywords=false; + } + + if (formatType.contains("2a") || formatType.contains("2b")) + distortionCorrection = false; + + missid = missid.simplified().trimmed(); + if (QString::compare(missid, "HAYABUSA-2", Qt::CaseInsensitive) != 0) { + QString msg = "Input file [" + fitsFileName + + "] does not appear to be a Hayabusa2 label file."; + throw IException(IException::Unknown, msg, _FILEINFO_); + } + instid = instid.simplified().trimmed(); + if (QString::compare(instid, "Optical Navigation Camera", Qt::CaseInsensitive) != 0) { + QString msg = "Input file [" + fitsFileName + + "] does not appear to be a Hayabusa2/ONC label file."; + throw IException(IException::Unknown, msg, _FILEINFO_); + } + + // Translate the Instrument group + + FileName transFile(transDir + "hyb2oncInstrument1.trn"); + + if (updatedKeywords) { + transFile = transDir+"hyb2oncInstrumentUpdated.trn"; + } + PvlToPvlTranslationManager instrumentXlater (fitsLabel, transFile.expanded()); + instrumentXlater.Auto(outputLabel); + + + // Update target if user specifies it + PvlGroup &instGrp = outputLabel.findGroup("Instrument",Pvl::Traverse); + + //Check for cropped image + int ss = instGrp["SelectedImageAreaX1"]; + int sl = instGrp["SelectedImageAreaY1"]; + int es = instGrp["SelectedImageAreaX2"]; + int el = instGrp["SelectedImageAreaY2"]; + + if (ss > 1 || sl >1 || es < N || el < N) { + + AlphaCube aCube(N, N, outputCube->sampleCount(), outputCube->lineCount(), + ss-0.5, sl - 0.5, es + 0.5, el + 0.5); + aCube.UpdateGroup(*outputCube); + + instGrp["SelectedImageAreaX1"] = "1"; + instGrp["SelectedImageAreaY1"] = "1"; + instGrp["SelectedImageAreaX2"] = QString("%1").arg(N); + instGrp["SelectedImageAreaY2"] = QString("%1").arg(N); + + + } + + QString labelTarget; + instGrp.addKeyword(PvlKeyword("DistortionCorrection")); + try { + labelTarget = fitsLabel.findGroup("FitsLabels").findKeyword("TARGET")[0]; + } + catch(IException &e) { + QString msg = "Unable to read TARGET from input file [" + +fitsFileName + "]"; + throw IException(e, IException::Io,msg, _FILEINFO_); + } + if (labelTarget=="SKY") { + instGrp["TargetName"] = "RYUGU"; + } + + if (distortionCorrection) { + instGrp["DistortionCorrection"] = "yes"; + } + else { + instGrp["DistortionCorrection"] = "no"; + } + + + //If the user wants to specify a different target, overwrite this value + if (target !="") { + instGrp["TargetName"] = target; + } + instGrp["ExposureDuration"].setUnits("seconds"); + outputCube->putGroup(instGrp); + + // Translate the BandBin group + + transFile = transDir + "hyb2oncBandBin.trn"; + if (updatedKeywords) { + transFile = transDir + "hyb2oncBandBinUpdated.trn"; + } + + + PvlToPvlTranslationManager bandBinXlater (fitsLabel, transFile.expanded()); + bandBinXlater.Auto(outputLabel); + PvlGroup &bandGrp = outputLabel.findGroup("BandBin",Pvl::Traverse); + if (bandGrp.hasKeyword("Width")) { // if width exists, then so must center + bandGrp["Width"].setUnits("nanometers"); + bandGrp["Center"].setUnits("nanometers"); + } + outputCube->putGroup(outputLabel.findGroup("BandBin",Pvl::Traverse)); + + // Translate the Archive group + + transFile = transDir + "hyb2oncArchive.trn"; + if (updatedKeywords) { + transFile = transDir + "hyb2oncArchiveUpdated.trn"; + } + + PvlToPvlTranslationManager archiveXlater (fitsLabel, transFile.expanded()); + archiveXlater.Auto(outputLabel); + PvlGroup &archGrp = outputLabel.findGroup("Archive", Pvl::Traverse); + QString source = archGrp.findKeyword("SourceProductId")[0]; + archGrp["SourceProductId"].setValue(FileName(source).baseName()); + + // Create YearDoy keyword in Archive group + iTime stime(outputLabel.findGroup("Instrument", Pvl::Traverse)["StartTime"][0]); + PvlKeyword yeardoy("YearDoy", toString(stime.Year()*1000 + stime.DayOfYear())); + archGrp.addKeyword(yeardoy); + outputCube->putGroup(archGrp); + + + // Create a Kernels group + if (updatedKeywords) { + transFile = transDir + "hyb2oncKernelsUpdated.trn"; + } + else { + transFile = transDir + "hyb2oncKernels.trn"; + } + + PvlToPvlTranslationManager kernelsXlater(fitsLabel, transFile.expanded()); + kernelsXlater.Auto(outputLabel); + outputCube->putGroup(outputLabel.findGroup("Kernels", Pvl::Traverse)); + + // Now write the FITS augmented label as the original label + // Save the input FITS label in the Cube original labels + OriginalLabel originalLabel(fitsLabel); + outputCube->write(originalLabel); + + // Convert the image data + importFits.Progress()->SetText("Importing Hayabusa2 image"); + importFits.StartProcess(); + importFits.Finalize(); + + return outputCube->label(); + + } + + + + + +} + diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h new file mode 100644 index 0000000000..cc4df40fae --- /dev/null +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h @@ -0,0 +1,17 @@ +#ifndef hyb2onc2isis_h +#define hyb2onc2isis_h + +#include +#include + +#include "Pvl.h" +#include "UserInterface.h" + +namespace Isis { + +extern void hyb2onc2isis(UserInterface &ui); +extern Pvl * hyb2onc2isis(QString &fitsFileName,QString &outputCubeFileName,QString target=""); + +} + +#endif diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp index fe2dadc693..115f935906 100644 --- a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp @@ -1,237 +1,14 @@ #include "Isis.h" -#include -#include - -#include "AlphaCube.h" -#include "FileName.h" -#include "iTime.h" -#include "OriginalLabel.h" -#include "ProcessImportFits.h" -#include "Pvl.h" -#include "PvlGroup.h" -#include "PvlKeyword.h" -#include "PvlObject.h" -#include "PvlToPvlTranslationManager.h" - +#include "hyb2onc2isis.h" #include "UserInterface.h" using namespace std; using namespace Isis; void IsisMain () { - - ProcessImportFits importFits; UserInterface &ui = Application::GetUserInterface(); - importFits.setFitsFile(FileName(ui.GetFileName("FROM"))); - importFits.setProcessFileStructure(0); - bool updatedKeywords = true; - bool distortionCorrection = true; - Cube *outputCube = importFits.SetOutputCube("TO"); - - // Get the directory where the Hayabusa translation tables are. - PvlGroup dataDir (Preference::Preferences().findGroup("DataDirectory")); - QString transDir = (QString) dataDir["Hayabusa2"] + "/translations/"; - - // Create a PVL to store the translated labels in - Pvl outputLabel; - - //Uncropped # of samples/lines - int N = 1024; - - - - // Get the FITS label - Pvl fitsLabel; - fitsLabel.addGroup(importFits.fitsImageLabel(0)); - try { - fitsLabel.addGroup(importFits.extraFitsLabel(0)); - } - catch (IException &e) { - QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() + - "] does not appear to be a Hayabusa2/ONC label file."; - throw IException(e, IException::Unknown, msg, _FILEINFO_); - } - - fitsLabel.write(FileName(ui.GetFileName("FROM")).expanded()+"fit.txt"); - - QString instid; - QString missid; - QString naifid; - QString formatType; - - try { - instid = fitsLabel.findGroup("FitsLabels").findKeyword("INSTRUME")[0]; - missid = fitsLabel.findGroup("FitsLabels").findKeyword ("SPCECRFT")[0]; - } - catch (IException &e) { - QString msg = "Unable to read instrument ID, [INSTRUME], or spacecraft ID, [SPCECRFT], " - "from input file [" + FileName(ui.GetFileName("FROM")).expanded() + "]"; - throw IException(e, IException::Io,msg, _FILEINFO_); - } - - try { - naifid = fitsLabel.findGroup("FitsLabels").findKeyword("NAIFID")[0]; - } - catch(IException &e) { - updatedKeywords=false; - } - - try { - formatType = fitsLabel.findGroup("FitsLabels").findKeyword("EXTNAME")[0]; - } - catch(IException &e) { - QString msg = "Unable to read EXTNAME from input file [" - +FileName(ui.GetFileName("FROM")).expanded() + "]"; - throw IException(e, IException::Io,msg, _FILEINFO_); - } - - try { - naifid = fitsLabel.findGroup("FitsLabels").findKeyword("NAIFID")[0]; - } - catch(IException &e) { - updatedKeywords=false; - } - - if (formatType.contains("2a") || formatType.contains("2b")) - distortionCorrection = false; - - missid = missid.simplified().trimmed(); - if (QString::compare(missid, "HAYABUSA-2", Qt::CaseInsensitive) != 0) { - QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() + - "] does not appear to be a Hayabusa2 label file."; - throw IException(IException::Unknown, msg, _FILEINFO_); - } - instid = instid.simplified().trimmed(); - if (QString::compare(instid, "Optical Navigation Camera", Qt::CaseInsensitive) != 0) { - QString msg = "Input file [" + FileName(ui.GetFileName("FROM")).expanded() + - "] does not appear to be a Hayabusa2/ONC label file."; - throw IException(IException::Unknown, msg, _FILEINFO_); - } - - // Translate the Instrument group - - FileName transFile(transDir + "hyb2oncInstrument1.trn"); - - if (updatedKeywords) { - transFile = transDir+"hyb2oncInstrumentUpdated.trn"; - } - PvlToPvlTranslationManager instrumentXlater (fitsLabel, transFile.expanded()); - instrumentXlater.Auto(outputLabel); - - - // Update target if user specifies it - PvlGroup &instGrp = outputLabel.findGroup("Instrument",Pvl::Traverse); - QString target; - - //Check for cropped image - - - int ss = instGrp["SelectedImageAreaX1"]; - int sl = instGrp["SelectedImageAreaY1"]; - int es = instGrp["SelectedImageAreaX2"]; - int el = instGrp["SelectedImageAreaY2"]; - - if (ss > 1 || sl >1 || es < N || el < N) { - - AlphaCube aCube(N, N, outputCube->sampleCount(), outputCube->lineCount(), - ss-0.5, sl - 0.5, es + 0.5, el + 0.5); - aCube.UpdateGroup(*outputCube); - - instGrp["SelectedImageAreaX1"] = "1"; - instGrp["SelectedImageAreaY1"] = "1"; - instGrp["SelectedImageAreaX2"] = QString("%1").arg(N); - instGrp["SelectedImageAreaY2"] = QString("%1").arg(N); - - - } - - instGrp.addKeyword(PvlKeyword("DistortionCorrection")); - try { - target = fitsLabel.findGroup("FitsLabels").findKeyword("TARGET")[0]; - } - catch(IException &e) { - QString msg = "Unable to read TARGET from input file [" - +FileName(ui.GetFileName("FROM")).expanded() + "]"; - throw IException(e, IException::Io,msg, _FILEINFO_); - } - if (target=="SKY") { - instGrp["TargetName"] = "RYUGU"; - } - - if (distortionCorrection) { - instGrp["DistortionCorrection"] = "yes"; - } - else { - instGrp["DistortionCorrection"] = "no"; - } - - - //If the user wants to specify a different target, overwrite this value - if (ui.WasEntered("TARGET")) { - instGrp["TargetName"] = ui.GetString("TARGET"); - } - instGrp["ExposureDuration"].setUnits("seconds"); - outputCube->putGroup(instGrp); - - // Translate the BandBin group - - transFile = transDir + "hyb2oncBandBin.trn"; - if (updatedKeywords) { - transFile = transDir + "hyb2oncBandBinUpdated.trn"; - } - - - PvlToPvlTranslationManager bandBinXlater (fitsLabel, transFile.expanded()); - bandBinXlater.Auto(outputLabel); - PvlGroup &bandGrp = outputLabel.findGroup("BandBin",Pvl::Traverse); - if (bandGrp.hasKeyword("Width")) { // if width exists, then so must center - bandGrp["Width"].setUnits("nanometers"); - bandGrp["Center"].setUnits("nanometers"); - } - outputCube->putGroup(outputLabel.findGroup("BandBin",Pvl::Traverse)); - - // Translate the Archive group - - transFile = transDir + "hyb2oncArchive.trn"; - if (updatedKeywords) { - transFile = transDir + "hyb2oncArchiveUpdated.trn"; - } - - PvlToPvlTranslationManager archiveXlater (fitsLabel, transFile.expanded()); - archiveXlater.Auto(outputLabel); - PvlGroup &archGrp = outputLabel.findGroup("Archive", Pvl::Traverse); - QString source = archGrp.findKeyword("SourceProductId")[0]; - archGrp["SourceProductId"].setValue(FileName(source).baseName()); - - // Create YearDoy keyword in Archive group - iTime stime(outputLabel.findGroup("Instrument", Pvl::Traverse)["StartTime"][0]); - PvlKeyword yeardoy("YearDoy", toString(stime.Year()*1000 + stime.DayOfYear())); - archGrp.addKeyword(yeardoy); - outputCube->putGroup(archGrp); - - - // Create a Kernels group - if (updatedKeywords) { - transFile = transDir + "hyb2oncKernelsUpdated.trn"; - } - else { - transFile = transDir + "hyb2oncKernels.trn"; - } - - PvlToPvlTranslationManager kernelsXlater(fitsLabel, transFile.expanded()); - kernelsXlater.Auto(outputLabel); - outputCube->putGroup(outputLabel.findGroup("Kernels", Pvl::Traverse)); - - // Now write the FITS augmented label as the original label - // Save the input FITS label in the Cube original labels - OriginalLabel originalLabel(fitsLabel); - outputCube->write(originalLabel); - - // Convert the image data - importFits.Progress()->SetText("Importing Hayabusa2 image"); - importFits.StartProcess(); - importFits.Finalize(); + hyb2onc2isis(ui); } diff --git a/isis/tests/hyb2onc2isisTests.cpp b/isis/tests/hyb2onc2isisTests.cpp new file mode 100644 index 0000000000..9860c4deea --- /dev/null +++ b/isis/tests/hyb2onc2isisTests.cpp @@ -0,0 +1,22 @@ +#include "hyb2onc2isis.h" +#include "Pvl.h" +#include + +#include + +//#include "gmock/gmock.h" + +using namespace Isis; + + + +TEST(stats,telescopic) { + + QString blah(""); + //QString fitsInput("/usgs/cpkgs/isis3/testData/isis/src/hayabusa2/apps/hyb2onc2isis/tsts/telescopic/hyb2_onc_20151204_040908_tvf_l2a.fit"); + //QString outputCube("hyb2_onc_20151204_040908_tvf_l2a.cub"); + hyb2onc2isis(blah,blah,""); + +EXPECT_EQ("blah","blah"); + +} From 8fa370e0d255ded00d82e6b67b7bc2c01a8c1cf6 Mon Sep 17 00:00:00 2001 From: Summer Stapleton Date: Wed, 19 Dec 2018 07:01:56 -0700 Subject: [PATCH 09/24] Removing build numbers from external libraries (#660) * Moved ISIS3 conda-build recipe from ISIS3_deps repository * Un-pinned non-astro build numbers * Removing build numbers from external libraries in the environment and meta.yeml files * Final merging --- environment.yml | 59 ++++++++++---------- environment_gcc4.yml | 57 ++++++++++---------- recipe/meta.yaml | 124 +++++++++++++++++++++---------------------- 3 files changed, 115 insertions(+), 125 deletions(-) diff --git a/environment.yml b/environment.yml index ea05a5b363..6ce26f1563 100644 --- a/environment.yml +++ b/environment.yml @@ -6,65 +6,62 @@ channels: dependencies: - armadillo==8.200.0 - - blas==1.1=openblas - - bullet==2.86.1=0 + - blas==1.1 + - bullet==2.86.1 - bz2file==0.98 - - bzip2==1.0.6=1 + - bzip2==1.0.6 - cmake>=3.10 - - cspice==66=h470a237_3 - - curl==7.60.0=0 - - doxygen==1.8.14=0 - - eigen==3.3.3=0 - - embree==2.14.0=0 + - cspice==66 + - curl==7.60.0 + - doxygen==1.8.14 + - eigen==3.3.3 + - embree==2.14.0 - geos==3.5.1 - - geotiff==1.4.2=1 + - geotiff==1.4.2 - gmm==5.0 - - gmp==6.1.2=0 - - gsl==2.2.1=blas_openblas_3 - - hdf5==1.8.18=2 - - icu==58.2=0 + - gmp==6.1.2 + - gsl==2.2.1 + - hdf5==1.8.18 + - icu==58.2 - jama==125 - - jpeg==9b=2 + - jpeg==9b - kakadu==1 - - krb5==1.14.2=0 + - krb5==1.14.2 - libpng>=1.6.34 - libprotobuf==3.5.2 - libtiff>=4.0.9 - - libxml2==2.9.7=0 + - libxml2==2.9.7 - make - - mesalib==17.2.0=0 + - mesalib==17.2.0 - mysql==5.7.20 - - mysql-connector-c==6.1.6=0 + - mysql-connector-c==6.1.6 - nanoflann==1.2.2 - - ninja==1.7.2=0 + - ninja==1.7.2 - conda-forge/label/gcc7::nn - # - numpy==1.13.3=py36_blas_openblas_200 - - openblas==0.2.19=2 + - openblas==0.2.19 - opencv - - openssl==1.0.2n=0 + - openssl==1.0.2n - patchelf==0.9 - pcl==1.8.1 - pip==9.0.1 - protobuf==3.5.2 - # - pyqt==5.6.0 - python==3.6 - qhull==7.2.0=0 - qt=5.9.6 - qwt=6.1.3 - setuptools=38.5.1 - sip==4.18 - - sqlite==3.13.0=1 - - suitesparse==4.5.4=blas_openblas_200 - - superlu==5.2.1=blas_openblas_201 + - sqlite==3.13.0 + - suitesparse==4.5.4 + - superlu==5.2.1 - tnt==126=0 - wheel==0.30.0 - x264==20131218 - xalan-c==1.11 - - xerces-c==3.1.4=0 - - xorg-kbproto==1.0.7=1 + - xerces-c==3.1.4 + - xorg-kbproto==1.0.7 - xorg-libice - xorg-libsm - - xorg-libx11==1.6.4=6 + - xorg-libx11==1.6.4 - xorg-libxi - - zlib==1.2.11=0 - + - zlib==1.2.11 diff --git a/environment_gcc4.yml b/environment_gcc4.yml index 9c76350031..92be4d2037 100644 --- a/environment_gcc4.yml +++ b/environment_gcc4.yml @@ -8,64 +8,61 @@ channels: dependencies: - armadillo==8.200.0 - blas==1.1=openblas - - bullet==2.86.1=0 + - bullet==2.86.1 - bz2file==0.98 - - bzip2==1.0.6=1 + - bzip2==1.0.6 - cmake>=3.10 - - cspice==66=h470a237_3 - - curl==7.60.0=0 - - doxygen==1.8.14=0 - - eigen==3.3.3=0 - - embree==2.14.0=0 + - cspice==66 + - curl==7.60.0 + - doxygen==1.8.14 + - eigen==3.3.3 + - embree==2.14.0 - geos==3.5.1 - - geotiff==1.4.2=1 + - geotiff==1.4.2 - gmm==5.0 - - gmp==6.1.2=0 - - gsl==2.2.1=blas_openblas_3 - - hdf5==1.8.18=2 - - icu==58.2=0 + - gmp==6.1.2 + - gsl==2.2.1 + - hdf5==1.8.18 + - icu==58.2 - jama==125 - - jpeg==9b=2 + - jpeg==9b - kakadu==1 - - krb5==1.14.2=0 + - krb5==1.14.2 - libpng>=1.6.34 - libprotobuf==3.5.2 - libtiff>=4.0.9 - - libxml2==2.9.7=0 + - libxml2==2.9.7 - make - - mesalib==17.2.0=0 + - mesalib==17.2.0 - mysql==5.7.20 - - mysql-connector-c==6.1.6=0 + - mysql-connector-c==6.1.6 - nanoflann==1.2.2 - - ninja==1.7.2=0 + - ninja==1.7.2 - nn==1.86.0 - # - numpy==1.13.3=py36_blas_openblas_200 - - openblas==0.2.19=2 + - openblas==0.2.19 - opencv - - openssl==1.0.2n=0 + - openssl==1.0.2n - patchelf==0.9 - pcl==1.8.1 - pip==9.0.1 - protobuf==3.5.2 - # - pyqt==5.6.0 - python==3.6 - qhull==7.2.0=0 - qt=5.9.6 - qwt=6.1.3 - setuptools=38.5.1 - sip==4.18 - - sqlite==3.13.0=1 - - suitesparse==4.5.4=blas_openblas_200 - - superlu==5.2.1=blas_openblas_201 + - sqlite==3.13.0 + - suitesparse==4.5.4 + - superlu==5.2.1 - tnt==126=0 - wheel==0.30.0 - x264==20131218 - xalan-c==1.11 - - xerces-c==3.1.4=0 - - xorg-kbproto==1.0.7=1 + - xerces-c==3.1.4 + - xorg-kbproto==1.0.7 - xorg-libice - xorg-libsm - - xorg-libx11==1.6.4=6 + - xorg-libx11==1.6.4 - xorg-libxi - - zlib==1.2.11=0 - + - zlib==1.2.11 diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 06b38780a0..04811fb260 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -1,5 +1,5 @@ {% set version = "3.6.1" %} -{% set git_branch = "dev" %} +{% set git_branch = "release" %} {% set build_number = "0" %} package: @@ -16,132 +16,128 @@ build: # Shotgun strat on requirements until we can narrow them down requirements: build: - - armadillo==8.200.0=blas_openblas_200 - - blas==1.1=openblas - - bullet==2.86.1=0 + - armadillo==8.200.0 + - blas==1.1 + - bullet==2.86.1 - bz2file==0.98 - - bzip2==1.0.6=1 + - bzip2==1.0.6 - cmake=>3.10 - - cspice==66=h470a237_3 - - curl==7.60.0=0 - - doxygen==1.8.14=0 - - eigen==3.3.3=0 - - embree==2.14.0=0 + - cspice==66 + - curl==7.60.0 + - doxygen==1.8.14 + - eigen==3.3.3 + - embree==2.14.0 - geos==3.5.1 - - geotiff==1.4.2=1 + - geotiff==1.4.2 - gmm==5.0 - - gmp==6.1.2=0 - - gsl==2.2.1=blas_openblas_3 - - hdf5==1.8.18=2 - - icu==58.2=0 + - gmp==6.1.2 + - gsl==2.2.1 + - hdf5==1.8.18 + - icu==58.2 - jama==125 - - jpeg==9b=2 + - jpeg==9b - kakadu==1 - - krb5==1.14.2=0 + - krb5==1.14.2 - libpng>=1.6.34 - libprotobuf==3.5.2 - libtiff=>4.0.9 - - libxml2==2.9.7=0 + - libxml2==2.9.7 - make - - mesalib==17.2.0=0 + - mesalib==17.2.0 - mysql==5.7.20 - - mysql-connector-c==6.1.6=0 + - mysql-connector-c==6.1.6 - nanoflann==1.2.2 - - ninja==1.7.2=0 + - ninja==1.7.2 - nn - # - numpy==1.13.3=py36_blas_openblas_200 - - openblas==0.2.19=2 + - openblas==0.2.19 - opencv==3.2.0|3.3.0 - - openssl==1.0.2n=0 + - openssl==1.0.2n - patchelf==0.9 - pcl==1.8.1 - pip==9.0.1 - protobuf==3.5.2 - # - pyqt==5.6.0 - python==3.6 - qhull==7.2.0=0 - qt=5.9.6 - qwt=6.1.3 - setuptools=38.5.1 - sip==4.18 - - sqlite==3.13.0=1 - - suitesparse==4.5.4=blas_openblas_200 - - superlu==5.2.1=blas_openblas_201 + - sqlite==3.13.0 + - suitesparse==4.5.4 + - superlu==5.2.1 - tnt==126=0 - wheel==0.30.0 - x264==20131218 - xalan-c==1.11 - - xerces-c==3.1.4=0 - - xorg-kbproto==1.0.7=1 + - xerces-c==3.1.4 + - xorg-kbproto==1.0.7 - xorg-libice - xorg-libsm - - xorg-libx11==1.6.4=6 + - xorg-libx11==1.6.4 - xorg-libxi - - zlib==1.2.11=0 + - zlib==1.2.11 run: - armadillo==8.200.0 - - blas==1.1=openblas - - bullet==2.86.1=0 + - blas==1.1 + - bullet==2.86.1 - bz2file==0.98 - - bzip2==1.0.6=1 - - cmake==3.9.1=0 - - cspice==66=h470a237_3 - - curl==7.60.0=0 - - doxygen==1.8.14=0 - - eigen==3.3.3=0 - - embree==2.14.0=0 + - bzip2==1.0.6 + - cmake==3.9.1 + - cspice==66 + - curl==7.60.0 + - doxygen==1.8.14 + - eigen==3.3.3 + - embree==2.14.0 - geos==3.5.1 - - geotiff==1.4.2=1 + - geotiff==1.4.2 - gmm==5.0 - - gmp==6.1.2=0 - - gsl==2.2.1=blas_openblas_3 - - hdf5==1.8.18=2 - - icu==58.2=0 + - gmp==6.1.2 + - gsl==2.2.1 + - hdf5==1.8.18 + - icu==58.2 - jama==125 - jasper=1 - - jpeg==9b=2 + - jpeg==9b - kakadu==1 - - krb5==1.14.2=0 + - krb5==1.14.2 - libpng>=1.6.34 - libprotobuf==3.5.2 - libtiff=>4.0.9 - - libxml2==2.9.7=0 + - libxml2==2.9.7 - make - - mesalib==17.2.0=0 + - mesalib==17.2.0 - mysql==5.7.20 - - mysql-connector-c==6.1.6=0 + - mysql-connector-c==6.1.6 - nanoflann==1.2.2 - - ninja==1.7.2=0 - - nn - # - numpy==1.13.3=py36_blas_openblas_200 - - openblas==0.2.19=2 + - ninja==1.7.2 + - conda-forge/label/gcc7::nn + - openblas==0.2.19 - opencv==3.2.0|3.3.0 - - openssl==1.0.2n=0 + - openssl==1.0.2n - patchelf==0.9 - pcl==1.8.1 - pip==9.0.1 - protobuf==3.5.2 - # - pyqt==5.6.0 - python==3.6 - qhull==7.2.0=0 - qt=5.9.6 - qwt=6.1.3 - setuptools=38.5.1 - sip==4.18 - - sqlite==3.13.0=1 - - suitesparse==4.5.4=blas_openblas_200 - - superlu==5.2.1=blas_openblas_201 + - sqlite==3.13.0 + - suitesparse==4.5.4 + - superlu==5.2.1 - tnt==126=0 - wheel==0.30.0 - x264==20131218 - xalan-c==1.11 - - xerces-c==3.1.4=0 - - xorg-kbproto==1.0.7=1 + - xerces-c==3.1.4 + - xorg-kbproto==1.0.7 - xorg-libice - xorg-libsm - - xorg-libx11==1.6.4=6 + - xorg-libx11==1.6.4 - xorg-libxi - - zlib==1.2.11=0 + - zlib==1.2.11 # Add the tests eventually # test: # From a92a0c49c2faebdc0fbaaf4817d4bff5e04bb717 Mon Sep 17 00:00:00 2001 From: Kaitlyn Lee Date: Wed, 19 Dec 2018 11:09:33 -0700 Subject: [PATCH 10/24] Added pixel type attribute to the output image of program shadow. Fixes #5187 (#659) * Removed bolding of some text to decrease distraction. * Fixed some typos. * Reworded documentation. --- isis/src/base/apps/shadow/shadow.xml | 131 ++++++++++++++------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/isis/src/base/apps/shadow/shadow.xml b/isis/src/base/apps/shadow/shadow.xml index b18e54baaa..f6f14fc0da 100644 --- a/isis/src/base/apps/shadow/shadow.xml +++ b/isis/src/base/apps/shadow/shadow.xml @@ -2,26 +2,28 @@ - High accuracy hillshade with shadow casting + Create a high accuracy hillshade with shadow casting - This program will create a shaded-relief cube from a DEM and match cube.

+ This program, shadow, will create a shaded-relief cube from a digital + elevation model (DEM) and a MATCH cube.

- This program operates much like 'shade' but instead of an azimuth/elevation input, we use the - sun's position at the center of the given cube or at a given time and, by default, factor in - shadows cast by features.

+ We use the sun's position at the center of the input cube or a user-defined + observation time. By default, we factor in shadows cast by features. + This program operates much like the ISIS3 'shade' program which instead requires azimuth/elevation as input.

- Using the sun's position allows much higher precision shading and enables the possibility of - computing shadowed areas. The algorithm description below is provided to help understand the + However, with the shadow application, using the sun's position allows much + higher precision shading and enables the possibility of computing shadowed areas. + The algorithm description below is provided to help understand the optimization settings.

User-Requirements
The user must supply an elevation model (DEM) and either an observation time or a cube - with raw camera geometry (see spiceinit).

+ with raw camera geometry (see 'spiceinit').

Understanding the Algorithm
- The shade program's algorithm is called 'hillshade' in this algorithm description. + The 'shade' program's algorithm is called 'hillshade' in this algorithm description.
  1. @@ -30,35 +32,32 @@
  2. - For every pixel in the input elevation model
    + For every pixel in the input elevation model, compute the hillshade value for the pixel, and
    1. - Compute the hillshade value for the pixel, and -
    2. -
    3. - if the hillshade result is positive (facing towards the sun) then estimate if the pixel is + if the hillshade result is positive (facing towards the sun), then estimate if the pixel is in shadow;
    4. - if the hillshade value is positive and the pixel is in shadow then the result is an LRS; + if the hillshade value is positive and the pixel is in shadow, then the result is an LRS;
    5. - if the hillshade value is positive and the pixel is not in shadow then the result is the + if the hillshade value is positive and the pixel is not in shadow, then the result is the hillshade result and
    6. - if the hillshade value is negative the result is an LRS + if the hillshade value is negative, the result is low resolution saturation (LRS).
- The algorithm to estimate if a pixel is in shadow + The algorithm to estimate if a pixel is in shadow:
  1. - Optimization: If SHADOW, and this elevation model pixel is known to be shadowed, + Optimization: If SHADOW, and this elevation model pixel is known to be shadowed, consider this pixel to be shadowed and stop (no pixels are initially known to be - shadowed). + shadowed).
  2. Compute the pixel's body-fixed coordinate (XYZ) position. @@ -68,7 +67,7 @@ the sun.
  3. - Subtract the sun's position from the elevation model pixel's position, giving you a vector + Subtract the sun's position from the elevation model pixel's position, providing a vector to the center (or edge) of the sun.
  4. @@ -84,10 +83,10 @@
  5. Update estimate of how far along the 3D ray is equivalent to the full resolution of the elevation model.
    - Optimization: Multiply the step by PRECISION.
    - Optimization : If SKIPOVERSHADOW, while the next linearly-extrapolated elevation + Optimization: Multiply the step by PRECISION.
    + Optimization : If SKIPOVERSHADOW, while the next linearly-extrapolated elevation model position is known to be in shadow, increase the next step size by the - estimate up to MAXSKIPOVERSHADOWSTEPS times
    . + estimate up to MAXSKIPOVERSHADOWSTEPS times.
  6. Check for a solution
    • @@ -98,9 +97,9 @@
    • If the ray's elevation is higher than the highest point on the elevation model, the originating pixel is in light.
      - Optimization: If LIGHTCURTAIN, and the ray's elevation is higher than a previous ray + Optimization: If LIGHTCURTAIN, and the ray's elevation is higher than a previous ray that intersected this pixel in the elevation model, consider the - originating pixel in light. + originating pixel in light.
  7. @@ -109,18 +108,18 @@
  8. If LIGHTCURTAIN, and the pixel was determined to be in light, record the elevations of the ray where it projected onto the elevation model.
    - Optimization: If LOWERLIGHTCURTAIN, lower the elevations along the ray by + Optimization: If LOWERLIGHTCURTAIN, lower the elevations along the ray by subtracting the minimum difference between the ray and the elevation model while - the ray was being walked..
    - Optimization: If CACHEINTERPOLATEDVALUES, linearly interpolate the points where the - ray would have intersected the elevation model to one pixel accuracy. + the ray was being walked.
    + Optimization: If CACHEINTERPOLATEDVALUES, linearly interpolate the points where the + ray would have intersected the elevation model to one pixel accuracy.
  9. If SHADOWMAP, and the pixel was determined to be in shadow, record all points where the ray projected onto the elevation model to be known shadowed points, excluding the actual intersection point.
    - Optimization: If CACHEINTERPOLATEDVALUES, linearly interpolate the points where the - ray would have intersected the elevation model to one pixel accuracy. + Optimization: If CACHEINTERPOLATEDVALUES, linearly interpolate the points where the + ray would have intersected the elevation model to one pixel accuracy.
  10. @@ -137,8 +136,8 @@ cache, and 16 bytes for the shadow cache, but the caches are hash-based causing a large amount of potential overhead. The caches are not limited to their specified sizes, only reduced to them periodically, and larger cache sizes result in this program consuming more memory. - Although the larger the cache, the longer takes to lookup a single value (which happens often), - in general larger caches mean less CPU time for the cost of memory. + The larger the cache, the longer it takes to lookup a single value (which happens often). + In general, larger caches mean less CPU time for the cost of memory. @@ -152,6 +151,10 @@ Added NaifStatus::CheckErrors() to see if any NAIF errors were signaled. References #2248. + + Added the PixelType attribute to the output cube and set it to real. + Documentation updated by editor. Fixes #5187. + @@ -170,6 +173,7 @@ cube + real output Shaded and shadowed DEM @@ -267,8 +271,8 @@ This is the estimated radius of the sun in solar radii. Since the unit "solar radius" is not our best guess of the sun's radius, the default is slightly different than 1. - A larger number has the end effect of lessening shadows, a smaller number increases - shadows. The sun's radius is only used for shadow computations, hillshade always uses the + A larger number has the end effect of lessening shadows; a smaller number increases + shadows. The sun's radius is only used for shadow computations. Hillshade always uses the sun's center. 0.0 @@ -291,8 +295,8 @@ This should be the time of the observer to use for the sun's position. The entered time - will be adjusted for light-time between the sun and the observer. The format should be: - "YYYY-MM-DDTHH:MM:SS.SSS" - for example: "2012-01-01T14:25:15.36" + will be adjusted for light-time between the sun and the observer. The format should be + "YYYY-MM-DDTHH:MM:SS.SSS"; for example, "2012-01-01T14:25:15.36" @@ -306,7 +310,7 @@ This is a list of quick settings for the other parameters in the Optimizations group. This also includes the ability to disable the shadow computations entirely. These options are - provided for those who don't need a lot of customization or don't want to calculate + provided for those who do not need a lot of customization or do not want to calculate shadow positions. @@ -417,10 +421,10 @@ When a ray is determined to be in shadow, every DEM pixel between the original position and - the point at which the DEM intersected the ray will be marked as in shadow. We then don't - have to do any significant work when processing a pixel we previously determined was in + the point at which the DEM intersected the ray will be marked as in shadow. We then perform no + significant work when processing a pixel that we previously determined was in shadow. This also helps avoid unnecessary ray-DEM intersection checks (because surfaces - aren't shadowed by surfaces already in shadow). + are not shadowed by surfaces already in shadow). BASESHADOWCACHESIZE @@ -436,8 +440,8 @@ The shadow cache is allowed to grow to an unlimited size while the shadowing algorithm is - processing. However, periodically the caches are shrunk - this is the approximate number - of elements to shrink the shadow cache to. The shrinking is optimized in a way that + processing. This is the approximate number of elements to shrink the + shadow cache to, as periodically the caches are shrunk. The shrinking is optimized in a way that is mostly respected, but not guaranteed. 0 @@ -480,8 +484,8 @@ The light curtain cache is allowed to grow to an unlimited size while the shadowing - algorithm is processing. However, periodically the caches are shrunk - this is the - approximate number of elements to shrink the light caches to. The shrinking is optimized + algorithm is processing. This is the approximate number of elements to + shrink the light caches to, as periodically the caches are shrunk. The shrinking is optimized in a way that this is mostly respected, but not guaranteed. 0 @@ -515,7 +519,7 @@ This is a means to lessen the number of ray-DEM intersection checks by guessing the - next ray-DEM intersection location and checking if it's in shadow. If it is, the ray + next ray-DEM intersection location and checking if it is in shadow. If it is, the ray is stepped farther before the next intersection test (up to MAXSKIPOVERSHADOWSTEPS farther). @@ -530,7 +534,7 @@ Distance to consider SKIPOVERSHADOW valid - Since the ray won't make a perfectly straight line across the DEM (DEMs are + Since the ray will not make a perfectly straight line across the DEM (DEMs are projected onto a flat surface) a linear guess as to the next intersection point degrades in accuracy (depending on a number of factors, such as ray elevation, projection type, and DEM accuracy). This controls how far the algorithm can guess the next intersection point @@ -547,7 +551,7 @@ This example will cover running this program in balanced mode. - The input file "localdem.cub" was produced with the commands: + The input file "localdem.cub" was produced with the following commands:
               spiceinit from=ab102401.cub
               fx from=ab102401.cub to=ab102401.radii.cub equation="radius(f1)"
    @@ -565,10 +569,10 @@
           
             
               
    -            Example's parameters in the graphical interface
    +            Example of parameters in the graphical interface
                 
    -              Run this program given a high resolution DEM 'localdem.cub' and the lighting
    -              characteristics from 'ab102401.cub' to create 'shadowed.cub'
    +              Run this program using the high resolution DEM 'localdem.cub' and the lighting
    +              characteristics from 'ab102401.cub' to create the 'shadowed.cub'
                 
                 
    @@ -579,8 +583,8 @@
             
               FROM DEM to do shaded relief and shadow calculations on
               
    -            This is the elevation model for which we're computing a shaded relief and shadow
    -            positions for. This is the FROM cube.
    +            This is the elevation model for which the shaded relief and shadow
    +            positions are to be computed. This is the FROM cube.
               
               
    @@ -588,7 +592,7 @@
             
               MATCH image for computing the sun position
               
    -            This is the image we're gathering the sun position from. In other words, we're trying
    +            We gather the sun position from this image. In other words, we are trying
                 to make the DEM look like this image.
               
               Output shaded relief with shadows
               
                 This is the result of the shadow program. This is the TO cube.
    -
                 The shadows are not as big as the shadows we see in the projected MATCH image because
    -            we're computing the fully shadowed areas in this program. Areas of the image that are
    -            getting less light, but aren't fully shadowed, look like they are in shadow but still
    -            have detail in them. To extend the shadow computations to encompass the visible
    +            we have computed the fully shadowed areas in this program. Areas of the image that are
    +            getting less light, but not fully shadowed, still appear in the shadow, but
    +            show more detail in them. To extend the shadow computations to encompass the visible
                 shadow completely you can turn off SUNEDGE.
               
               
                 Example's parameters in the graphical interface
                 
    -              Run this program given a the DEM 'dem.cub' and the lighting
    -              characteristics from midnight March 1st, 2012 to create 'shadowed_dem.cub'
    +              Run this program given the DEM 'dem.cub' and the lighting
    +              characteristics from midnight March 1st, 2012 to create 'shadowed_dem.cub'.
                 
                 
    @@ -661,8 +664,8 @@
             
               FROM DEM to do shaded relief and shadow calculations on
               
    -            This is the elevation model for which we're computing a shaded relief and shadow
    -            positions for. This is the FROM cube.
    +            This is the elevation model for which the shaded relief and shadow
    +            positions are to be computed. This is the FROM cube.
               
               
    @@ -674,7 +677,7 @@
               
                 This is the result of the shadow program. This is the TO cube.
     
    -            This is what a mosaic of the entire moon would look like, approximately, if all of the
    +            This is what a mosaic of the entire moon would look like, approximately, if all
                 images were taken at one time.
               
               
    Date: Wed, 19 Dec 2018 12:00:03 -0700
    Subject: [PATCH 11/24] Added section for Environment and PreferemcesSetup in
     the Getting Started Section. (#663)
    
    ---
     isis/src/docsys/build/UserDocs.xsl | 26 ++++++++++++++++++--------
     1 file changed, 18 insertions(+), 8 deletions(-)
    
    diff --git a/isis/src/docsys/build/UserDocs.xsl b/isis/src/docsys/build/UserDocs.xsl
    index f0d384b09b..243485b417 100644
    --- a/isis/src/docsys/build/UserDocs.xsl
    +++ b/isis/src/docsys/build/UserDocs.xsl
    @@ -1,7 +1,7 @@
     
    -
     
     
     
     
    -  
             
    
             
    @@ -129,11 +129,22 @@ Deborah Lee Soltesz
                 ISIS Workshop
               
               
    -          Interactive and hands-on tutorials designed to guide users through the basics of using ISIS 
    +          Interactive and hands-on tutorials designed to guide users through the basics of using ISIS
     	  to advanced processing techniques for creating mosaics from mission data,
               correcting and enhancing problem data, and other techniques.
               
             
    +        
    +          
    +            
    +            Environment and Preference Setup
    +          
    +          
    +          A guide on how to setup your Unix environment in order to run ISIS.
    +          It also discusses the ISIS Preference files, which gives the user the
    +          ability to customize the operation of ISIS.
    +          
    +        
     
           
           
    Date: Wed, 19 Dec 2018 19:39:38 -0700
    Subject: [PATCH 13/24] Added build type release to conda recipe (#676)
    
    ---
     recipe/build.sh | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/recipe/build.sh b/recipe/build.sh
    index 3ace2b9456..ef8368ae31 100644
    --- a/recipe/build.sh
    +++ b/recipe/build.sh
    @@ -1,5 +1,5 @@
     mkdir build
     cd build
    -cmake -GNinja -DJP2KFLAG=ON -Dpybindings=OFF -DCMAKE_INSTALL_PREFIX=$PREFIX -Disis3Data=/usgs/cpkgs/isis3/data -Disis3TestData=/usgs/cpkgs/isis3/testData ../isis
    +cmake -GNinja -DJP2KFLAG=ON -Dpybindings=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX -Disis3Data=/usgs/cpkgs/isis3/data -Disis3TestData=/usgs/cpkgs/isis3/testData ../isis
     ninja install
     ninja docs
    
    From 401b2cf42d375c692d3cae9b23c6411b17ce9e63 Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Tue, 29 Jan 2019 17:21:11 -0700
    Subject: [PATCH 14/24] Modified isis/tests/CMakeLists.txt as well as
     hyb2onc2isis to fix unresolved symbol errors (CMakeLists.txt) and to fix some
     bugs in hyb2onc2isis involved with turning it into a callable function.
    
    ---
     .../apps/hyb2onc2isis/hyb2onc2isis.cpp        | 24 ++++++++++++++-----
     .../apps/hyb2onc2isis/hyb2onc2isis.h          |  2 +-
     isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp |  3 ++-
     isis/tests/CMakeLists.txt                     |  8 ++++++-
     4 files changed, 28 insertions(+), 9 deletions(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    index b76d1cd09c..83410f8e0e 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    @@ -2,6 +2,7 @@
     
     #include "AlphaCube.h"
     #include "Application.h"
    +#include "CubeAttribute.h"
     #include "FileName.h"
     #include "iTime.h"
     #include "OriginalLabel.h"
    @@ -25,32 +26,42 @@ namespace Isis {
     
     void hyb2onc2isis(UserInterface &ui) {
     
    -  ProcessImportFits importFits;
     
    -  QString fitsFileName = FileName(ui.GetFileName("FROM")).expanded();
    +
    +  QString fitsFileName = FileName(ui.GetFileName("FROM")).expanded();  
    +
    +
    +
    +
       QString outputCubeFileName = FileName(ui.GetFileName("TO")).expanded();
     
    +
       QString target("");
       if (ui.WasEntered("TARGET")) {
         target = ui.GetString("TARGET");
       }
     
       // Create a PVL to store the translated labels in
    -  Pvl * outputLabel = hyb2onc2isis(fitsFileName,outputCubeFileName,target);
    +  hyb2onc2isis(fitsFileName,outputCubeFileName,target);
    +
     
       return;
     
       }
     
     
    -Pvl * hyb2onc2isis(QString &fitsFileName, QString &outputCubeFileName, QString target) {
    +Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target) {
     
       ProcessImportFits importFits;
       importFits.setFitsFile(FileName(fitsFileName));
       importFits.setProcessFileStructure(0);
       bool updatedKeywords = true;
       bool distortionCorrection = true;
    -  Cube *outputCube = importFits.SetOutputCube(outputCubeFileName);
    +
    +  CubeAttributeOutput &att =
    +    Application::GetUserInterface().GetOutputAttribute("TO");
    +
    +  Cube *outputCube = importFits.SetOutputCube(outputCubeFileName,att);
     
       // Get the directory where the Hayabusa translation tables are.
       PvlGroup dataDir (Preference::Preferences().findGroup("DataDirectory"));
    @@ -250,7 +261,8 @@ Pvl * hyb2onc2isis(QString &fitsFileName, QString &outputCubeFileName, QString t
       importFits.StartProcess();
       importFits.Finalize();
     
    -  return outputCube->label();
    +
    +  return outputLabel;
     
       }
     
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    index cc4df40fae..deff201b04 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    @@ -10,7 +10,7 @@
     namespace Isis {
     
     extern void hyb2onc2isis(UserInterface &ui);
    -extern Pvl * hyb2onc2isis(QString &fitsFileName,QString &outputCubeFileName,QString target="");
    +extern Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target="");
     
     }
     
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp
    index 115f935906..6c007acd53 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/main.cpp
    @@ -1,7 +1,8 @@
     #include "Isis.h"
    +#include "UserInterface.h"
     
     #include "hyb2onc2isis.h"
    -#include "UserInterface.h"
    +
     
     using namespace std;
     using namespace Isis;
    diff --git a/isis/tests/CMakeLists.txt b/isis/tests/CMakeLists.txt
    index dd5bf29f16..ffdcbfefcc 100644
    --- a/isis/tests/CMakeLists.txt
    +++ b/isis/tests/CMakeLists.txt
    @@ -5,11 +5,17 @@ add_dependencies(isis3 isis3)
     file(GLOB test_source "${CMAKE_SOURCE_DIR}/tests/*.cpp")
     
     
    +
     # Link runISISTests with what we want to test and the GTest and pthread library
     add_executable(runISISTests
                    IsisTestMain.cpp
                    ${test_source})
    +
    +#message("All libraries being linked against:  ")
    +#message("${ALLLIBS}")               
                    
    -target_link_libraries(runISISTests isis3 ${ALLLIBS} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread)
    +target_link_libraries(runISISTests isis3 ${ALLLIBS} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} hayabusa2 pthread)
     
     gtest_discover_tests(runISISTests WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests)
    +
    +message(STATUS "${GTEST_LIBRARIES}")
    
    From 78e8bce8bf7bd1e4bf4118cc6d26339ead5b9d9b Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Wed, 30 Jan 2019 16:47:44 -0700
    Subject: [PATCH 15/24] Added w1 test to hyb2onc2isisTests.cpp
    
    ---
     .../apps/hyb2onc2isis/hyb2onc2isis.cpp        | 19 ++++---
     .../apps/hyb2onc2isis/hyb2onc2isis.h          |  4 +-
     isis/tests/hyb2onc2isisTests.cpp              | 49 ++++++++++++++++---
     3 files changed, 54 insertions(+), 18 deletions(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    index 83410f8e0e..6f38ae616a 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    @@ -30,9 +30,6 @@ void hyb2onc2isis(UserInterface &ui) {
     
       QString fitsFileName = FileName(ui.GetFileName("FROM")).expanded();  
     
    -
    -
    -
       QString outputCubeFileName = FileName(ui.GetFileName("TO")).expanded();
     
     
    @@ -41,16 +38,20 @@ void hyb2onc2isis(UserInterface &ui) {
         target = ui.GetString("TARGET");
       }
     
    -  // Create a PVL to store the translated labels in
    -  hyb2onc2isis(fitsFileName,outputCubeFileName,target);
    +  CubeAttributeOutput &att =
    +    ui.GetOutputAttribute("TO");
    +
     
     
    +  // Create a PVL to store the translated labels in
    +  hyb2onc2isis(fitsFileName,outputCubeFileName,att,target);
    +
       return;
     
       }
     
     
    -Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target) {
    +Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttributeOutput att, QString target) {
     
       ProcessImportFits importFits;
       importFits.setFitsFile(FileName(fitsFileName));
    @@ -58,9 +59,6 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target
       bool updatedKeywords = true;
       bool distortionCorrection = true;
     
    -  CubeAttributeOutput &att =
    -    Application::GetUserInterface().GetOutputAttribute("TO");
    -
       Cube *outputCube = importFits.SetOutputCube(outputCubeFileName,att);
     
       // Get the directory where the Hayabusa translation tables are.
    @@ -85,7 +83,6 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target
         throw IException(e, IException::Unknown, msg, _FILEINFO_);
       }
     
    -
       QString instid;
       QString missid;
       QString naifid;
    @@ -258,12 +255,14 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target
     
       // Convert the image data
       importFits.Progress()->SetText("Importing Hayabusa2 image");
    +   Pvl finalLabel = *(outputCube->label() );
       importFits.StartProcess();
       importFits.Finalize();
     
     
       return outputLabel;
     
    +
       }
     
     
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    index deff201b04..51db22756a 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.h
    @@ -4,13 +4,15 @@
     #include 
     #include 
     
    +#include "CubeAttribute.h"
     #include "Pvl.h"
     #include "UserInterface.h"
     
     namespace Isis {
     
     extern void hyb2onc2isis(UserInterface &ui);
    -extern Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,QString target="");
    +extern Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,CubeAttributeOutput att,
    +                        QString target="");
     
     }
     
    diff --git a/isis/tests/hyb2onc2isisTests.cpp b/isis/tests/hyb2onc2isisTests.cpp
    index 9860c4deea..5e1b213fc6 100644
    --- a/isis/tests/hyb2onc2isisTests.cpp
    +++ b/isis/tests/hyb2onc2isisTests.cpp
    @@ -1,22 +1,57 @@
     #include "hyb2onc2isis.h"
    +#include "FileName.h"
    +#include "CubeAttribute.h"
     #include "Pvl.h"
    +
    +#include 
     #include 
     
    -#include 
     
    +#include 
    +#include 
    +#include 
    +
    +#include 
     //#include "gmock/gmock.h"
     
     using namespace Isis;
    +using namespace std;
    +
    +
    +//QString testDataPath("/usgs/cpkgs/isis3/testData/isis/src");
    +
    +QString testDataPath=("/scratch/isis3hayabusa2/tsts");
    +
    +
    +TEST(hyb2onc2isis,w1) {
    +
    +  //QString w1Fits(testDataPath+"/hayabusa2/apps/hyb2onc2isis/tsts/w1/input/hyb2_onc_20151204_041027_w1f_l2a.fit");
    +  QString w1Fits=(testDataPath+"/w1/input/hyb2_onc_20151204_041027_w1f_l2a.fit");
    +  QString outputCube("temp.cub");
    +
    +  CubeAttributeOutput att;
    +  att.addAttribute("real");
    +  Pvl outputLabel = hyb2onc2isis(w1Fits, outputCube,att);
    +
    +
    +  ofstream w1pvl;
    +  w1pvl << outputLabel;
    +
    +  ifstream truthpvl(testDataPath.toStdString()+"/w1/truth/labels.pvl");
    +  stringstream buffer;
    +  buffer << w1pvl.rdbuf();
    +  string w1pvlstr = buffer.str();
     
    +  //Flush the buffer
    +  buffer.str(std::string());
     
    +  //Read the truth data Pvl file
    +  buffer << truthpvl.rdbuf();
    +  string truthpvlstr = buffer.str();
     
    -TEST(stats,telescopic) {
    +  remove("temp.cub");
     
    -  QString blah("");
    - //QString fitsInput("/usgs/cpkgs/isis3/testData/isis/src/hayabusa2/apps/hyb2onc2isis/tsts/telescopic/hyb2_onc_20151204_040908_tvf_l2a.fit");
    - //QString outputCube("hyb2_onc_20151204_040908_tvf_l2a.cub");
    - hyb2onc2isis(blah,blah,"");
     
    -EXPECT_EQ("blah","blah");
    +  EXPECT_EQ(w1pvlstr,truthpvlstr);
     
     }
    
    From e6db077b535063e4bf87d20be330cc2f75c9c4e0 Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Fri, 1 Feb 2019 10:53:22 -0700
    Subject: [PATCH 16/24] Modified hyb2onccal to be a callable function.
    
    ---
     .../apps/hyb2onccal/Hyb2OncCalUtils.h         | 359 ++++++++-
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.cpp  | 420 ++++++++++
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.h    |  15 +
     isis/src/hayabusa2/apps/hyb2onccal/main.cpp   | 730 +-----------------
     4 files changed, 792 insertions(+), 732 deletions(-)
     create mode 100644 isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
     create mode 100644 isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.h
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    index abd60f27c9..e2ef7e6a7a 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    @@ -1,22 +1,50 @@
     #ifndef Hyb2OncCalUtils_h
     #define Hyb2OncCalUtils_h
     
    -#include 
    +
    +
    +
    +#include "CSVReader.h"
    +#include "IException.h"
    +#include "LineManager.h"
    +#include "NaifStatus.h"
    +
    +
    +
     #include 
     #include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
     #include 
    +#include 
     #include 
    +#include 
    +#include 
    +#include 
     
    -#include "CSVReader.h"
    -#include "IException.h"
    +#include "AlphaCube.h"
    +#include "Buffer.h"
     #include "FileName.h"
    +#include "IException.h"
    +#include "iTime.h"
     #include "LineManager.h"
    -#include "NaifStatus.h"
    -#include "IString.h"
    +#include "Pixel.h"
    +#include "ProcessByLine.h"
    +#include "ProcessBySample.h"
    +#include "ProcessByBrick.h"
    +#include "ProcessByBoxcar.h"
    +#include "ProgramLauncher.h"
     #include "Pvl.h"
     #include "PvlGroup.h"
    -
     #include "Spice.h"
    +#include "Statistics.h"
    +#include "TextFile.h"
    +
    +
     
     
     
    @@ -32,8 +60,230 @@
     using namespace cv;
     using namespace std;
     
    +
    +static int g_bitDepth(12);
    +
    +//For subimage and binning mapping
    +
    +static bool g_cropped(true);
    +
    +static QString g_filter = "";
    +static QString g_target ="";
    +
    +
    +//Bias calculation variables
    +static double g_b0(0);
    +static double g_b1(0);
    +static double g_b2(0);
    +static double g_bae0(0);
    +static double g_bae1(0);
    +static double g_bias(0);
    +
    +//Device (AE/CCD/ECT temps for ONC-T,ONC-W1,ONC-W2
    +
    +static double g_AEtemperature(0.0);
    +
    +static double g_CCD_T_temperature(0.0);
    +static double g_ECT_T_temperature(0.0);
    +
    +
    +static double g_CCD_W1_temperature(0.0);
    +static double g_ECT_W1_temperature(0.0);
    +
    +
    +static double g_CCD_W2_temperature(0.0);
    +static double g_ECT_W2_temperature(0.0);
    +
    +
    +static QString g_startTime;
    +
    +//Dark Current variables
    +static double g_d0(0);
    +static double g_d1(0);
    +static double g_darkCurrent(0);
    +
    +//Linearity correction variables
    +static double g_L0(0);
    +static double g_L1(0);
    +static double g_L2(0);
    +
    +// TODO: we do not have the readout time (transfer period) for Hayabusa2 ONC.
    +//Smear calculation variables
    +static bool g_onBoardSmearCorrection(false);
    +static double g_Tvct(0);       // Vertical charge-transfer period (in seconds).
    +static double g_texp(1);       // Exposure time.
    +static double g_timeRatio(1.0);
    +
    +// Calibration parameters
    +static int binning(1);         //!< The number of samples/lines which are binned
    +static double g_compfactor(1.0);  // Default if OutputMode = LOSS-LESS; 16.0 for LOSSY
    +
    +static QString g_iofCorrection("IOF");  //!< Is I/F correction to be applied?
    +
    +//  I/F variables
    +static double g_solarDist(1.0);  /**< Distance from the Sun to the target body
    +(used to calculate g_iof) */
    +static double g_iof(1.0);        //!< I/F conversion value
    +static double g_iofScale(1.0);
    +static double g_solarFlux(1.0);  //!< The solar flux (used to calculate g_iof).
    +// TODO: we do not have this conversion factor for Hayabusa 2 ONC.
    +static double g_v_standard(1.0);
    +// static double g_v_standard(3.42E-3);//!< Base conversion for all filters (Tbl. 9)
    +
     namespace Isis {
     
    +// Temporary cube file pointer deleter
    +struct TemporaryCubeDeleter {
    +  static inline void cleanup(Cube *cube) {
    +    if ( cube ) {
    +
    +      FileName filename( cube->fileName() );
    +      delete cube;
    +      remove( filename.expanded().toLatin1().data() );
    +    }
    +  }
    +};
    +
    +enum InstrumentType{ONCW1,ONCW2,ONCT};
    +InstrumentType g_instrument;
    +
    +static AlphaCube *alpha(0);
    +
    +static Pvl g_configFile;
    +
    +
    +/**
    +* @brief Apply radiometric correction to each line of an AMICA image.
    +* @author 2016-03-30 Kris Becker
    +* @param in   Raw image and flat field
    +* @param out  Radometrically corrected image
    +* @internal
    +*   @history 2017-07-2017 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    +*/
    +void Calibrate(vector& in, vector& out) {
    +
    +  Buffer& imageIn   = *in[0];
    +  Buffer& flatField = *in[1];
    +  Buffer& imageOut  = *out[0];
    +
    +  int pixelsToNull = 0;
    +
    +  // Note that is isn't currently tested, as we do not have a test with a hayabusa2 image that
    +  // has been on-board cropped.
    +  int currentSample = imageIn.Sample();
    +  int alphaSample = alpha->AlphaSample(currentSample);
    +
    +  if ( (alphaSample <= pixelsToNull)  || (alphaSample >= (1024 - pixelsToNull ) ) ) {
    +
    +    for (int i = 0; i < imageIn.size(); i++ ) {
    +      imageOut[i] = Isis::Null;
    +    }
    +    return;
    +  }
    +
    +  // Iterate over the line space
    +  for (int i = 0; i < imageIn.size(); i++) {
    +    imageOut[i] = imageIn[i]*pow(2.0,12-g_bitDepth);
    +
    +
    +
    +    // Check for special pixel in input image and pass through
    +    if ( IsSpecial(imageOut[i]) ) {
    +      imageOut[i] = imageIn[i];
    +      continue;
    +    }
    +
    +    // Apply compression factor here to raise LOSSY dns to proper response
    +    imageOut[i] *= g_compfactor;
    +
    +
    +    // 1) BIAS Removal - Only needed if not on-board corrected
    +
    +
    +    if ( !g_onBoardSmearCorrection ) {
    +
    +
    +      if ( (imageOut[i] - g_bias) <= 0.0) {
    +        imageOut[i] = Null;
    +        continue;
    +      }
    +      else {
    +        imageOut[i] = imageOut[i] - g_bias;
    +      }
    +    }
    +
    +
    +#if 0
    +    double linearCorrection;
    +    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    +    imageOut[i]*=linearCorrection;
    +
    +#endif
    +
    +
    +    // DARK Current
    +    imageOut[i] = imageOut[i] - g_darkCurrent;
    +
    +
    +
    +
    +    // READOUT Smear Removal - Not needed if on-board corrected.  Binning is
    +    //    accounted for in computation of c1 before loop.
    +    // if (nsubImages <= 1) {
    +    //  imageOut[i] = c1*(imageOut[i] - smear);
    +    // }
    +    if (!g_onBoardSmearCorrection) {
    +
    +      double smear = 0;
    +      for (int j=0;j < imageIn.size();j++) {
    +        smear += (imageOut[j]/imageIn.size() );
    +      }
    +      smear*=g_timeRatio;
    +      imageOut[i] = imageOut[i] - smear;
    +
    +      }
    +
    +    //Linearity Correction
    +    //In the SIS this adjustment is made just after the bias, but
    +    //in the Calibration paper it happens just before the flat field correction.
    +
    +#if 0
    +    double linearCorrection;
    +    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    +    qDebug() << "linearCorrection=" << linearCorrection;
    +    imageOut[i]*=linearCorrection;
    + #endif
    +
    +
    +    // FLATFIELD correction
    +    //  Check for any special pixels in the flat field (unlikely)
    +    // If we have only one input cube, that means that we do not have a flat-field (W1/W2).
    +    if (in.size() == 2) {
    +      // Note that our current flat-fields to not have special pixel values.
    +      if ( IsSpecial(flatField[i])  || IsSpecial(imageOut[i]) )
    +      {
    +        imageOut[i] = Isis::Null;
    +        continue;
    +      }
    +      else {
    +        if (flatField[i] != 0) {
    +          imageOut[i] /= flatField[i];
    +        }
    +      }
    +    }
    +
    +    // TODO: once the radiance values are known for each band, we can correctly compute I/F.
    +    // For now, g_iof is 1, so output will be in DNs.
    +    // 7) I/F or Radiance Conversion (or g_iof might = 1, in which case the output will be in DNs)
    +    imageOut[i] *= g_iof;
    +
    +  }
    +
    +
    +  return;
    +}
    +
    +
     
     /**
      * @brief Load required NAIF kernels required for timing needs.
    @@ -254,12 +504,109 @@ void  translate(Cube *flatField,double *transform, QString fname) {
     }
     
     
    +/**
    +* @brief Determine name of flat field file to apply
    +* @author 2016-03-30 Kris Becker
    +* @param filter  Name of ONC filter
    +* @return FileName Path and name of flat file file
    +* @internal
    +*   @history 2017-07-27 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    +*/
    +FileName DetermineFlatFieldFile(const QString &filter) {
    +
    +  QString fileName = "$hayabusa2/calibration/flatfield/";
    +  // FileName consists of binned/notbinned, camera, and filter
    +  fileName += "flat_" + filter.toLower() + ".cub";
    +  FileName final(fileName);
    +  return final;
    +}
    +
    +
    +/**
    +* @brief Loads the calibration variables into the program.
    +* @param config QString Name of the calibration file to load.
    +*
    +* Loads g_b0-g_b2,g_bae0-g_bae1,g_d0-g_d1
    +*
    +*
    +*/
    +QString loadCalibrationVariables(const QString &config)  {
    +
    +
    +
    +  //  UserInterface& ui = Application::GetUserInterface();
    +
    +  FileName calibFile(config);
    +  if ( config.contains("?") ) calibFile = calibFile.highestVersion();
     
    +  // Pvl configFile;
    +  g_configFile.read(calibFile.expanded());
     
    +  // Load the groups
    +  PvlGroup &Bias = g_configFile.findGroup("Bias");
    +  PvlGroup &DarkCurrent = g_configFile.findGroup("DarkCurrent");
    +  PvlGroup &Smear = g_configFile.findGroup("SmearRemoval");
    +  PvlGroup &solar = g_configFile.findGroup("SOLARFLUX");
    +  PvlGroup &linearity = g_configFile.findGroup("Linearity");
    +  // PvlGroup &iof = g_configFile.findGroup("RAD");
     
    +  // Load Smear Removal Variables
    +  g_Tvct = Smear["Tvct"];
     
     
     
    +  // Load DarkCurrent variables and calculate the dark current
    +  g_d0 = DarkCurrent["D"][0].toDouble();
    +  g_d1 = DarkCurrent["D"][1].toDouble();
    +  double CCDTemp(0.0);
    +
    +  switch (g_instrument) {
    +    case InstrumentType::ONCT:
    +      CCDTemp = g_CCD_T_temperature;
    +    break;
    +    case InstrumentType::ONCW1:
    +      CCDTemp = g_CCD_W1_temperature;
    +    break;
    +    case InstrumentType::ONCW2:
    +      CCDTemp = g_CCD_W2_temperature;
    +    break;
    +    default:
    +      CCDTemp = g_CCD_T_temperature;
    +  }
    +
    +   g_darkCurrent = g_texp*exp(0.10*CCDTemp+0.52);
    +
    +  // Load Bias variables
    +  g_b0 = Bias["B"][0].toDouble();
    +  g_b1 = Bias["B"][1].toDouble();
    +  g_b2 = Bias["B"][2].toDouble();
    +  g_bae0 = Bias["B_AE"][0].toDouble();
    +  g_bae1 = Bias["B_AE"][1].toDouble();
    +
    +
    +
    +  // Compute BIAS correction factor (it's a constant so do it once!)
    +  g_bias = g_b0+g_b1*g_CCD_T_temperature+g_b2*g_ECT_T_temperature;
    +  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //correction factor
    +  qDebug() << "Bias: " << g_bias;
    +
    +  // Load the Solar Flux for the specific filter
    +  g_solarFlux = solar[g_filter.toLower()];
    +
    +  //Load the linearity variables
    +  g_L0 = linearity["L"][0].toDouble();
    +  g_L1 = linearity["L"][1].toDouble();
    +  g_L2 = linearity["L"][2].toDouble();
    +
    +
    +  // radiance = g_v_standard * g_iofScale
    +  // iof      = radiance * pi *dist_au^2
    +  // g_iofScale   = iof[g_filter];
    +
    +  return ( calibFile.original() );
    +}
    +
    +
     
     
     
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    new file mode 100644
    index 0000000000..145fa318df
    --- /dev/null
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    @@ -0,0 +1,420 @@
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#include "Application.h"
    +#include "AlphaCube.h"
    +#include "Buffer.h"
    +#include "FileName.h"
    +#include "hyb2onccal.h"
    +#include "Hyb2OncCalUtils.h"
    +#include "IException.h"
    +#include "iTime.h"
    +#include "LineManager.h"
    +#include "Pixel.h"
    +#include "ProcessByLine.h"
    +#include "ProcessBySample.h"
    +#include "ProcessByBrick.h"
    +#include "ProcessByBoxcar.h"
    +#include "ProgramLauncher.h"
    +#include "Pvl.h"
    +#include "PvlGroup.h"
    +#include "Spice.h"
    +#include "Statistics.h"
    +#include "TextFile.h"
    +
    +
    +
    +using namespace std;
    +
    +
    +//void Calibrate(vector& in, vector& out);
    +
    +//QString loadCalibrationVariables(const QString &config);
    +
    +
    +
    +namespace Isis {
    +
    +void hyb2onccal(UserInterface &ui) {
    +
    +
    +  // g_iofCorrection = ui.GetString("UNITS");
    +
    +  const QString hyb2cal_program = "hyb2onccal";
    +  const QString hyb2cal_version = "1.1";
    +  const QString hyb2cal_revision = "$Revision$";
    +  QString hyb2cal_runtime = Application::DateTime();
    +
    +  ProcessBySample p;
    +
    +  Cube *icube = p.SetInputCube("FROM");
    +
    +  // Basic assurances...
    +  if (icube->bandCount() != 1) {
    +    throw IException(IException::User,
    +      "ONC images may only contain one band", _FILEINFO_);
    +    }
    +
    +  PvlGroup &inst = icube->group("Instrument");
    +  PvlGroup &bandbin = icube->group("BandBin");
    +
    +  try{
    +    g_filter = bandbin["FilterName"][0];
    +  }
    +
    +  catch(IException &e) {
    +    QString msg = "Unable to read FilterName keyword in the BandBin group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +
    +  }
    +
    +  QString instrument("");
    +
    +  try {
    +    instrument = inst["InstrumentId"][0];
    +  }
    +  catch(IException &e) {
    +    QString msg = "Unable to read InstrumentId keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +
    +  }
    +
    +  if ( instrument=="ONC-W1" ) {
    +    g_instrument = InstrumentType::ONCW1;
    +  }
    +  else if ( instrument=="ONC-W2" ) {
    +    g_instrument = InstrumentType::ONCW2;
    +  }
    +  else if ( instrument == "ONC-T" ) {
    +      g_instrument = InstrumentType::ONCT;
    +  }
    +  else {
    +        QString msg = "Unidentified instrument key in the "
    +                      "InstrumentId key of the Instrument Pvl group.";
    +          throw IException(IException::Io,msg, _FILEINFO_);
    +  }
    +
    +
    +
    +  //Set up binning and image subarea mapping
    +  binning = inst["Binning"];
    +  int startLine = inst["SelectedImageAreaY1"];
    +  int startSample = inst["SelectedImageAreaX1"];
    +  int lastLine = inst["SelectedImageAreaY2"];
    +  int lastSample = inst["SelectedImageAreaX2"];
    +
    +  AlphaCube myAlpha(1024,1024,icube->sampleCount(), icube->lineCount(),
    +  startSample,startLine,lastSample,lastLine);
    +
    +  try {
    +    g_bitDepth = inst["BitDepth"];
    +  }
    +  catch (IException &e) {
    +    QString msg = "Unable to read [BitDepth] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    //qDebug() << msg;
    +    g_bitDepth = 12;
    +
    +  }
    +
    +
    +
    +  if (g_bitDepth < 0) {
    +    g_bitDepth = 12;  //Correpsonds to no correction being done for bit depth
    +  }
    +
    +  alpha = &myAlpha;
    +
    +  try {
    +    g_texp = inst["ExposureDuration"][0].toDouble();
    +  }
    +  catch(IException &e) {
    +    QString msg = "Unable to read [ExposureDuration] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +  }
    +
    +
    +  try {
    +    g_AEtemperature = inst["ONCAETemperature"][0].toDouble();
    +    qDebug() << "g_AEtemperature:  " << g_AEtemperature;
    +  }
    +  catch(IException &e) {
    +    QString msg = "Unable to read [ONCAETemperature] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +
    +  }
    +
    +  try {
    +    g_CCD_T_temperature = inst["ONCTCCDTemperature"][0].toDouble();
    +    qDebug() << "g_CCD_T_Temperature:  " << g_CCD_T_temperature;
    +  }
    +  catch(IException &e) {
    +    QString msg = "Unable to read [ONCTCCDTemperature] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +  }
    +
    +  try {
    +    g_ECT_T_temperature = inst["ONCTElectricCircuitTemperature"][0].toDouble();
    +    qDebug() << "g_ECT_T_temperature: " << g_ECT_T_temperature;
    +  }
    +  catch(IException &e) {
    +    QString msg = "Unable to read [ONCTElectricCircuitTemperature] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +  }
    +
    +
    +  try {
    +
    +    g_startTime=inst["SpacecraftClockStartCount"][0];
    +  }
    +
    +  catch (IException &e) {
    +    QString msg = "Unable to read [SpacecraftClockStartCount] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +  }
    +
    +
    +  QString smearCorrection;
    +
    +  try {
    +    smearCorrection = inst["SmearCorrection"][0];
    +  }
    +
    +  catch (IException &e) {
    +    QString msg = "Unable to read [SmearCorrection] keyword in the Instrument group "
    +    "from input file [" + icube->fileName() + "]";
    +    throw IException(e, IException::Io,msg, _FILEINFO_);
    +  }
    +
    +  if (smearCorrection=="ONBOARD") {
    +    g_onBoardSmearCorrection=true;
    +  }
    +
    +  QString compmode = inst["Compression"];
    +  // TODO: verify that the compression factor/scale is actually 16 for compressed Hayabusa2 images.
    +  g_compfactor = ( "lossy" == compmode.toLower() ) ? 16.0 : 1.0;
    +
    +  QString target = inst["TargetName"];
    +  g_target = target;
    +
    +
    +  // NOTE we do not have a valid flat-field for the W1 or W2 images.
    +  FileName flatfile = "NONE";
    +  PvlGroup alphaCube;
    +
    +  if (g_instrument == InstrumentType::ONCT) {
    +    QScopedPointer flatcube;
    +    flatfile = DetermineFlatFieldFile(g_filter);
    +    QString reducedFlat(flatfile.expanded());
    +
    +    try {
    +      alphaCube = icube->group("AlphaCube");
    +    }
    +
    +   catch(IException &e) {
    +     g_cropped =false;
    +    }
    +
    +    // Image is not cropped
    +    if (!g_cropped) {
    +
    +      // Determine if we need to subsample the flat field if pixel binning occurred
    +      // TODO: test a binned image (add test case).
    +      if (binning > 1) {
    +        QString scale(toString(binning));
    +        FileName newflat = FileName::createTempFile("$TEMPORARY/" +
    +        flatfile.baseName() + "_reduced.cub");
    +        reducedFlat = newflat.expanded();
    +        QString parameters = "FROM=" + flatfile.expanded() +
    +        " TO="   + newflat.expanded() +
    +        " MODE=SCALE" +
    +        " LSCALE=" + scale +
    +        " SSCALE=" + scale;
    +
    +        try {
    +          ProgramLauncher::RunIsisProgram("reduce", parameters);
    +        }
    +        catch (IException& ie) {
    +          remove(reducedFlat.toLatin1().data());
    +          throw ie;
    +        }
    +        //QScopedPointer reduced(new Cube(reducedFlat, "r"));
    +        //flatcube.swap( reduced );
    +      }
    +
    +      // Set up processing for flat field as a second input file
    +      CubeAttributeInput att;
    +      p.SetInputCube(reducedFlat, att);
    +    }
    +    else {
    +
    +      // Image is cropped so we have to deal with it
    +      FileName transFlat =
    +      FileName::createTempFile("$TEMPORARY/" + flatfile.baseName() + "_translated.cub");
    +
    +      Cube *flatOriginal = new Cube(flatfile.expanded() );
    +
    +      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
    +
    +      double alphaStartSample = alphaCube["AlphaStartingSample"][0].toDouble();
    +      double alphaStartLine = alphaCube["AlphaStartingLine"][0].toDouble();
    +      double alphaEndSample = alphaCube["AlphaEndingSample"][0].toDouble();
    +      double alphaEndLine = alphaCube["AlphaEndingLine"][0].toDouble();
    +
    +      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
    +      double transform[5] = {(double)binning,alphaStartSample,alphaStartLine,alphaEndSample,alphaEndLine};
    +
    +      // Translates and scales the flatfield image.  Scaling
    +      // might be necessary in the event that the raw image was also binned.
    +
    +      translate(flatOriginal,transform,transFlat.expanded());
    +
    +      QScopedPointer translated(new Cube(transFlat.expanded(), "r"));
    +      flatcube.swap(translated);
    +
    +      CubeAttributeInput att;
    +
    +      p.SetInputCube(transFlat.expanded(),att);
    +
    +  }  //Finished setting flatfield file for ONC-T
    +
    + }
    +
    +
    +
    +  Cube *ocube  = p.SetOutputCube("TO");
    +  //QString fname = ocube->fileName();
    +
    +  QString calfile = loadCalibrationVariables(ui.GetAsString("CONFIG"));
    +
    +  g_timeRatio = g_Tvct/(g_texp + g_Tvct);
    +
    +  g_iof = 1.0;  // Units of DN
    +
    +  QString g_units = "DN";
    +  // if ( "radiance" == g_iofCorrection.toLower() ) {
    +  //   // Units of RADIANCE
    +  //   g_iof = g_iof * g_iofScale;
    +  //   g_units = "W / (m**2 micrometer sr)";
    +  // }
    +  //
    +  // if ( !sunDistanceAU(startTime, target, g_solarDist) ) {
    +  //    throw IException(IException::Programmer, "Cannot calculate distance to sun!",
    +  //                      _FILEINFO_);
    +  // }
    +  //
    +  // if ( "iof" == g_iofCorrection.toLower() ) {
    +  //   // Units of I/F
    +  //   // TODO: Note, we do not have a correct g_iofScale (== 1 right now). This was provided for
    +  //   // Hayabusa AMICA's v-band and all other bands were normalized according to this value. We do
    +  //   // not have this value for Hayabusa2 ONC. Need to correct this value.
    +  //   g_iof = pi_c() * (g_solarDist * g_solarDist) *
    +  //           g_iofScale / g_solarFlux / g_texp;
    +  //   g_units = "I over F";
    +  // }
    +
    +  // Calibrate!
    +  try {
    +    p.Progress()->SetText("Calibrating Hayabusa2 Cube");
    +    p.StartProcess(Calibrate);
    +  }
    +  catch (IException &ie) {
    +    throw IException(ie, IException::Programmer,
    +      "Radiometric calibration failed!", _FILEINFO_);
    +  }
    +
    +  // Log calibration activity performed so far
    +  PvlGroup calibrationLog("RadiometricCalibration");
    +  calibrationLog.addKeyword(PvlKeyword("SoftwareName", hyb2cal_program));
    +  calibrationLog.addKeyword(PvlKeyword("SoftwareVersion", hyb2cal_version));
    +  calibrationLog.addKeyword(PvlKeyword("ProcessDate", hyb2cal_runtime));
    +  calibrationLog.addKeyword(PvlKeyword("CalibrationFile", calfile));
    +  calibrationLog.addKeyword(PvlKeyword("FlatFieldFile", flatfile.originalPath()
    +  + "/" + flatfile.name()));
    +  calibrationLog.addKeyword(PvlKeyword("CompressionFactor", toString(g_compfactor, 2)));
    +
    +  // Parameters
    +  PvlKeyword bn("Bias_Bn");
    +  bn.addValue(toString(g_b0, 8));
    +  bn.addValue(toString(g_b1, 8));
    +  bn.addValue(toString(g_b2, 8));
    +  calibrationLog.addKeyword(bn);
    +
    +  PvlKeyword bnae("Bias_AECorrection");
    +  bnae.addValue(toString(g_bae0, 8));
    +  bnae.addValue(toString(g_bae1, 8));
    +  calibrationLog.addKeyword(bnae);
    +
    +#if 0
    +  PvlKeyword linearityCoefs("Linearity");
    +  linearityCoefs.addValue(toString(g_L0,8));
    +  linearityCoefs.addValue(toString(g_L1,8));
    +  linearityCoefs.addValue(toString(g_L2,8));
    +  calibrationLog.addKeyword(linearityCoefs);
    +
    +#endif
    +
    +
    +  calibrationLog.addKeyword(PvlKeyword("Bias_AETemp", toString(g_AEtemperature, 16)));
    +
    +
    +  switch (g_instrument) {
    +
    +    case InstrumentType::ONCT:
    +       calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_T_temperature, 16)));
    +       calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_T_temperature, 16)));
    +    break;
    +
    +    case InstrumentType::ONCW1:
    +      calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_W1_temperature, 16)));
    +      calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_W1_temperature, 16)));
    +      break;
    +
    +    case InstrumentType::ONCW2:
    +      calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_W2_temperature, 16)));
    +      calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_W2_temperature, 16)));
    +      break;
    +  }
    +
    +  calibrationLog.addKeyword(PvlKeyword("Bias", toString(g_bias, 16), "DN"));
    +  calibrationLog.addKeyword(PvlKeyword("Smear_Tvct", toString(g_Tvct, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("Smear_texp", toString(g_texp, 16)));
    +
    +  calibrationLog.addKeyword(PvlKeyword("CalibrationUnits", g_iofCorrection));
    +  calibrationLog.addKeyword(PvlKeyword("RadianceStandard", toString(g_v_standard, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("RadianceScaleFactor", toString(g_iofScale, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("SolarDistance", toString(g_solarDist, 16), "AU"));
    +  calibrationLog.addKeyword(PvlKeyword("SolarFlux", toString(g_solarFlux, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("IOFFactor", toString(g_iof, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("Units", g_units));
    +
    +  // Write Calibration group to output file
    +  ocube->putGroup(calibrationLog);
    +  Application::Log(calibrationLog);
    +  //configFile.clear();
    +  p.EndProcess();
    +
    +}
    +
    +
    +
    +}
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.h b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.h
    new file mode 100644
    index 0000000000..e7078b94a4
    --- /dev/null
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.h
    @@ -0,0 +1,15 @@
    +#ifndef HYB2ONCCAL_H
    +#define HYB2ONCCAL_H
    +
    +#include "UserInterface.h"
    +
    +namespace Isis {
    +
    +  extern void hyb2onccal(UserInterface &ui);
    +
    +}
    +
    +
    +
    +
    +#endif // HYB2ONCCAL_H
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/main.cpp b/isis/src/hayabusa2/apps/hyb2onccal/main.cpp
    index c4dd5a160e..c3049f5bb9 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/main.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/main.cpp
    @@ -1,733 +1,11 @@
    -// $Id: hyb2onccal.cpp 6045 2015-02-07 02:06:59Z moses@GS.DOI.NET $
     #include "Isis.h"
     
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#include "AlphaCube.h"
    -#include "Buffer.h"
    -#include "FileName.h"
    -#include "Hyb2OncCalUtils.h"
    -#include "IException.h"
    -#include "iTime.h"
    -#include "LineManager.h"
    -#include "Pixel.h"
    -#include "ProcessByLine.h"
    -#include "ProcessBySample.h"
    -#include "ProcessByBrick.h"
    -#include "ProcessByBoxcar.h"
    -#include "ProgramLauncher.h"
    -#include "Pvl.h"
    -#include "PvlGroup.h"
    -#include "Spice.h"
    -#include "Statistics.h"
    -#include "TextFile.h"
    -
    +#include "UserInterface.h"
    +#include "hyb2onccal.h"
     
     using namespace Isis;
    -using namespace std;
    -
    -// Calibration support routines
    -FileName DetermineFlatFieldFile(const QString &filter);
    -void Calibrate(vector& in, vector& out);
    -
    -QString loadCalibrationVariables(const QString &config);
    -
    -// Temporary cube file pointer deleter
    -struct TemporaryCubeDeleter {
    -  static inline void cleanup(Cube *cube) {
    -    if ( cube ) {
    -
    -      FileName filename( cube->fileName() );
    -      delete cube;
    -      remove( filename.expanded().toLatin1().data() );
    -    }
    -  }
    -};
    -
    -enum InstrumentType{ONCW1,ONCW2,ONCT};
    -
    -static int g_bitDepth(12);
    -
    -InstrumentType g_instrument;
    -//For subimage and binning mapping
    -static AlphaCube *alpha(0);
    -static bool g_cropped(true);
    -
    -static QString g_filter = "";
    -static QString g_target ="";
    -static Pvl g_configFile;
    -
    -//Bias calculation variables
    -static double g_b0(0);
    -static double g_b1(0);
    -static double g_b2(0);
    -static double g_bae0(0);
    -static double g_bae1(0);
    -static double g_bias(0);
    -
    -//Device (AE/CCD/ECT temps for ONC-T,ONC-W1,ONC-W2
    -
    -static double g_AEtemperature(0.0);
    -
    -static double g_CCD_T_temperature(0.0);
    -static double g_ECT_T_temperature(0.0);
    -
    -
    -static double g_CCD_W1_temperature(0.0);
    -static double g_ECT_W1_temperature(0.0);
    -
    -
    -static double g_CCD_W2_temperature(0.0);
    -static double g_ECT_W2_temperature(0.0);
    -
    -
    -static QString g_startTime;
    -
    -//Dark Current variables
    -static double g_d0(0);
    -static double g_d1(0);
    -static double g_darkCurrent(0);
    -
    -//Linearity correction variables
    -static double g_L0(0);
    -static double g_L1(0);
    -static double g_L2(0);
    -
    -// TODO: we do not have the readout time (transfer period) for Hayabusa2 ONC.
    -//Smear calculation variables
    -static bool g_onBoardSmearCorrection(false);
    -static double g_Tvct(0);       // Vertical charge-transfer period (in seconds).
    -static double g_texp(1);       // Exposure time.
    -static double g_timeRatio(1.0);
    -
    -// Calibration parameters
    -static int binning(1);         //!< The number of samples/lines which are binned
    -static double g_compfactor(1.0);  // Default if OutputMode = LOSS-LESS; 16.0 for LOSSY
    -
    -static QString g_iofCorrection("IOF");  //!< Is I/F correction to be applied?
    -
    -//  I/F variables
    -static double g_solarDist(1.0);  /**< Distance from the Sun to the target body
    -(used to calculate g_iof) */
    -static double g_iof(1.0);        //!< I/F conversion value
    -static double g_iofScale(1.0);
    -static double g_solarFlux(1.0);  //!< The solar flux (used to calculate g_iof).
    -// TODO: we do not have this conversion factor for Hayabusa 2 ONC.
    -static double g_v_standard(1.0);
    -// static double g_v_standard(3.42E-3);//!< Base conversion for all filters (Tbl. 9)
     
     void IsisMain() {
    -
    -  UserInterface& ui = Application::GetUserInterface();
    -  // g_iofCorrection = ui.GetString("UNITS");
    -
    -  const QString hyb2cal_program = "hyb2onccal";
    -  const QString hyb2cal_version = "1.1";
    -  const QString hyb2cal_revision = "$Revision$";
    -  QString hyb2cal_runtime = Application::DateTime();
    -
    -  ProcessBySample p;
    -
    -  Cube *icube = p.SetInputCube("FROM");
    -
    -  // Basic assurances...
    -  if (icube->bandCount() != 1) {
    -    throw IException(IException::User,
    -      "ONC images may only contain one band", _FILEINFO_);
    -    }
    -
    -  PvlGroup &inst = icube->group("Instrument");
    -  PvlGroup &bandbin = icube->group("BandBin");
    -
    -  try{
    -    g_filter = bandbin["FilterName"][0];
    -  }
    -
    -  catch(IException &e) {
    -    QString msg = "Unable to read FilterName keyword in the BandBin group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -
    -  }
    -
    -  QString instrument("");
    -
    -  try {
    -    instrument = inst["InstrumentId"][0];
    -  }
    -  catch(IException &e) {
    -    QString msg = "Unable to read InstrumentId keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -
    -  }
    -
    -  if ( instrument=="ONC-W1" ) {
    -    g_instrument = InstrumentType::ONCW1;
    -  }
    -  else if ( instrument=="ONC-W2" ) {
    -    g_instrument = InstrumentType::ONCW2;
    -  }
    -  else if ( instrument == "ONC-T" ) {
    -      g_instrument = InstrumentType::ONCT;
    -  }
    -  else {
    -        QString msg = "Unidentified instrument key in the "
    -                      "InstrumentId key of the Instrument Pvl group.";
    -          throw IException(IException::Io,msg, _FILEINFO_);
    -  }
    -
    -
    -
    -  //Set up binning and image subarea mapping
    -  binning = inst["Binning"];
    -  int startLine = inst["SelectedImageAreaY1"];
    -  int startSample = inst["SelectedImageAreaX1"];
    -  int lastLine = inst["SelectedImageAreaY2"];
    -  int lastSample = inst["SelectedImageAreaX2"];
    -
    -  AlphaCube myAlpha(1024,1024,icube->sampleCount(), icube->lineCount(),
    -  startSample,startLine,lastSample,lastLine);
    -
    -  try {
    -    g_bitDepth = inst["BitDepth"];
    -  }
    -  catch (IException &e) {
    -    QString msg = "Unable to read [BitDepth] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    //qDebug() << msg;
    -    g_bitDepth = 12;
    -
    -  }
    -
    -
    -
    -  if (g_bitDepth < 0) {
    -    g_bitDepth = 12;  //Correpsonds to no correction being done for bit depth
    -  }
    -
    -  alpha = &myAlpha;
    -
    -  try {
    -    g_texp = inst["ExposureDuration"][0].toDouble();
    -  }
    -  catch(IException &e) {
    -    QString msg = "Unable to read [ExposureDuration] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -  }
    -
    -
    -  try {
    -    g_AEtemperature = inst["ONCAETemperature"][0].toDouble();
    -    qDebug() << "g_AEtemperature:  " << g_AEtemperature;
    -  }
    -  catch(IException &e) {
    -    QString msg = "Unable to read [ONCAETemperature] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -
    -  }
    -
    -  try {  
    -    g_CCD_T_temperature = inst["ONCTCCDTemperature"][0].toDouble();
    -    qDebug() << "g_CCD_T_Temperature:  " << g_CCD_T_temperature;
    -  }
    -  catch(IException &e) {
    -    QString msg = "Unable to read [ONCTCCDTemperature] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -  }
    -
    -  try {
    -    g_ECT_T_temperature = inst["ONCTElectricCircuitTemperature"][0].toDouble();
    -    qDebug() << "g_ECT_T_temperature: " << g_ECT_T_temperature;
    -  }
    -  catch(IException &e) {
    -    QString msg = "Unable to read [ONCTElectricCircuitTemperature] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -  }
    -
    -
    -  try {
    -
    -    g_startTime=inst["SpacecraftClockStartCount"][0];
    -  }
    -
    -  catch (IException &e) {
    -    QString msg = "Unable to read [SpacecraftClockStartCount] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -  }
    -
    -
    -  QString smearCorrection;
    -
    -  try {
    -    smearCorrection = inst["SmearCorrection"][0];
    -  }
    -
    -  catch (IException &e) {
    -    QString msg = "Unable to read [SmearCorrection] keyword in the Instrument group "
    -    "from input file [" + icube->fileName() + "]";
    -    throw IException(e, IException::Io,msg, _FILEINFO_);
    -  }
    -
    -  if (smearCorrection=="ONBOARD") {
    -    g_onBoardSmearCorrection=true;
    -  }
    -
    -  QString compmode = inst["Compression"];
    -  // TODO: verify that the compression factor/scale is actually 16 for compressed Hayabusa2 images.
    -  g_compfactor = ( "lossy" == compmode.toLower() ) ? 16.0 : 1.0;
    -
    -  QString target = inst["TargetName"];
    -  g_target = target;
    -
    -
    -  // NOTE we do not have a valid flat-field for the W1 or W2 images.
    -  FileName flatfile = "NONE";
    -  PvlGroup alphaCube;
    -
    -  if (g_instrument == InstrumentType::ONCT) {
    -    QScopedPointer flatcube;
    -    flatfile = DetermineFlatFieldFile(g_filter);
    -    QString reducedFlat(flatfile.expanded());
    -
    -    try {
    -      alphaCube = icube->group("AlphaCube");
    -    }
    -
    -   catch(IException &e) {
    -     g_cropped =false;
    -    }
    -
    -    // Image is not cropped
    -    if (!g_cropped) {
    -
    -      // Determine if we need to subsample the flat field if pixel binning occurred
    -      // TODO: test a binned image (add test case).
    -      if (binning > 1) {
    -        QString scale(toString(binning));
    -        FileName newflat = FileName::createTempFile("$TEMPORARY/" +
    -        flatfile.baseName() + "_reduced.cub");
    -        reducedFlat = newflat.expanded();
    -        QString parameters = "FROM=" + flatfile.expanded() +
    -        " TO="   + newflat.expanded() +
    -        " MODE=SCALE" +
    -        " LSCALE=" + scale +
    -        " SSCALE=" + scale;
    -
    -        try {
    -          ProgramLauncher::RunIsisProgram("reduce", parameters);
    -        }
    -        catch (IException& ie) {
    -          remove(reducedFlat.toLatin1().data());
    -          throw ie;
    -        }
    -        //QScopedPointer reduced(new Cube(reducedFlat, "r"));
    -        //flatcube.swap( reduced );
    -      }
    -
    -      // Set up processing for flat field as a second input file
    -      CubeAttributeInput att;
    -      p.SetInputCube(reducedFlat, att);
    -    }
    -    else {
    -
    -      // Image is cropped so we have to deal with it
    -      FileName transFlat =
    -      FileName::createTempFile("$TEMPORARY/" + flatfile.baseName() + "_translated.cub");
    -
    -      Cube *flatOriginal = new Cube(flatfile.expanded() );
    -
    -      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
    -
    -      double alphaStartSample = alphaCube["AlphaStartingSample"][0].toDouble();
    -      double alphaStartLine = alphaCube["AlphaStartingLine"][0].toDouble();
    -      double alphaEndSample = alphaCube["AlphaEndingSample"][0].toDouble();
    -      double alphaEndLine = alphaCube["AlphaEndingLine"][0].toDouble();
    -
    -      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
    -      double transform[5] = {(double)binning,alphaStartSample,alphaStartLine,alphaEndSample,alphaEndLine};
    -
    -      // Translates and scales the flatfield image.  Scaling
    -      // might be necessary in the event that the raw image was also binned.
    -
    -      translate(flatOriginal,transform,transFlat.expanded());
    -
    -      QScopedPointer translated(new Cube(transFlat.expanded(), "r"));
    -      flatcube.swap(translated);
    -
    -      CubeAttributeInput att;   
    -
    -      p.SetInputCube(transFlat.expanded(),att);
    -
    -  }  //Finished setting flatfield file for ONC-T
    -
    - }
    -
    -
    -
    -  Cube *ocube  = p.SetOutputCube("TO");
    -  //QString fname = ocube->fileName();
    -
    -  QString calfile = loadCalibrationVariables(ui.GetAsString("CONFIG"));
    -
    -  g_timeRatio = g_Tvct/(g_texp + g_Tvct);
    -
    -  g_iof = 1.0;  // Units of DN
    -
    -  QString g_units = "DN";
    -  // if ( "radiance" == g_iofCorrection.toLower() ) {
    -  //   // Units of RADIANCE
    -  //   g_iof = g_iof * g_iofScale;
    -  //   g_units = "W / (m**2 micrometer sr)";
    -  // }
    -  //
    -  // if ( !sunDistanceAU(startTime, target, g_solarDist) ) {
    -  //    throw IException(IException::Programmer, "Cannot calculate distance to sun!",
    -  //                      _FILEINFO_);
    -  // }
    -  //
    -  // if ( "iof" == g_iofCorrection.toLower() ) {
    -  //   // Units of I/F
    -  //   // TODO: Note, we do not have a correct g_iofScale (== 1 right now). This was provided for
    -  //   // Hayabusa AMICA's v-band and all other bands were normalized according to this value. We do
    -  //   // not have this value for Hayabusa2 ONC. Need to correct this value.
    -  //   g_iof = pi_c() * (g_solarDist * g_solarDist) *
    -  //           g_iofScale / g_solarFlux / g_texp;
    -  //   g_units = "I over F";
    -  // }
    -
    -  // Calibrate!
    -  try {
    -    p.Progress()->SetText("Calibrating Hayabusa2 Cube");   
    -    p.StartProcess(Calibrate);
    -  }
    -  catch (IException &ie) {
    -    throw IException(ie, IException::Programmer,
    -      "Radiometric calibration failed!", _FILEINFO_);
    -  }
    -
    -  // Log calibration activity performed so far
    -  PvlGroup calibrationLog("RadiometricCalibration");
    -  calibrationLog.addKeyword(PvlKeyword("SoftwareName", hyb2cal_program));
    -  calibrationLog.addKeyword(PvlKeyword("SoftwareVersion", hyb2cal_version));
    -  calibrationLog.addKeyword(PvlKeyword("ProcessDate", hyb2cal_runtime));
    -  calibrationLog.addKeyword(PvlKeyword("CalibrationFile", calfile));
    -  calibrationLog.addKeyword(PvlKeyword("FlatFieldFile", flatfile.originalPath()
    -  + "/" + flatfile.name()));
    -  calibrationLog.addKeyword(PvlKeyword("CompressionFactor", toString(g_compfactor, 2)));
    -
    -  // Parameters
    -  PvlKeyword bn("Bias_Bn");
    -  bn.addValue(toString(g_b0, 8));
    -  bn.addValue(toString(g_b1, 8));
    -  bn.addValue(toString(g_b2, 8));
    -  calibrationLog.addKeyword(bn);
    -
    -  PvlKeyword bnae("Bias_AECorrection");
    -  bnae.addValue(toString(g_bae0, 8));
    -  bnae.addValue(toString(g_bae1, 8));
    -  calibrationLog.addKeyword(bnae);
    -
    -#if 0
    -  PvlKeyword linearityCoefs("Linearity");
    -  linearityCoefs.addValue(toString(g_L0,8));
    -  linearityCoefs.addValue(toString(g_L1,8));
    -  linearityCoefs.addValue(toString(g_L2,8));
    -  calibrationLog.addKeyword(linearityCoefs);
    -
    -#endif
    -
    -
    -  calibrationLog.addKeyword(PvlKeyword("Bias_AETemp", toString(g_AEtemperature, 16)));
    -
    -
    -  switch (g_instrument) {
    -
    -    case InstrumentType::ONCT:
    -       calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_T_temperature, 16)));
    -       calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_T_temperature, 16)));
    -    break;
    -
    -    case InstrumentType::ONCW1:
    -      calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_W1_temperature, 16)));
    -      calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_W1_temperature, 16)));
    -      break;
    -
    -    case InstrumentType::ONCW2:
    -      calibrationLog.addKeyword(PvlKeyword("Bias_CCDTemp", toString(g_CCD_W2_temperature, 16)));
    -      calibrationLog.addKeyword(PvlKeyword("Bias_ECTTemp", toString(g_ECT_W2_temperature, 16)));
    -      break;
    -  }
    -
    -  calibrationLog.addKeyword(PvlKeyword("Bias", toString(g_bias, 16), "DN"));
    -  calibrationLog.addKeyword(PvlKeyword("Smear_Tvct", toString(g_Tvct, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("Smear_texp", toString(g_texp, 16)));
    -
    -  calibrationLog.addKeyword(PvlKeyword("CalibrationUnits", g_iofCorrection));
    -  calibrationLog.addKeyword(PvlKeyword("RadianceStandard", toString(g_v_standard, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("RadianceScaleFactor", toString(g_iofScale, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("SolarDistance", toString(g_solarDist, 16), "AU"));
    -  calibrationLog.addKeyword(PvlKeyword("SolarFlux", toString(g_solarFlux, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("IOFFactor", toString(g_iof, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("Units", g_units));
    -
    -  // Write Calibration group to output file
    -  ocube->putGroup(calibrationLog);
    -  Application::Log(calibrationLog);
    -  //configFile.clear();
    -  p.EndProcess();
    -
    -}
    -
    -
    -/**
    -* @brief Determine name of flat field file to apply
    -* @author 2016-03-30 Kris Becker
    -* @param filter  Name of ONC filter
    -* @return FileName Path and name of flat file file
    -* @internal
    -*   @history 2017-07-27 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    -*/
    -FileName DetermineFlatFieldFile(const QString &filter) {
    -
    -  QString fileName = "$hayabusa2/calibration/flatfield/";
    -  // FileName consists of binned/notbinned, camera, and filter
    -  fileName += "flat_" + filter.toLower() + ".cub";
    -  FileName final(fileName);
    -  return final;
    -}
    -
    -
    -
    -/**
    -* @brief Loads the calibration variables into the program.
    -* @param config QString Name of the calibration file to load.
    -*
    -* Loads g_b0-g_b2,g_bae0-g_bae1,g_d0-g_d1
    -*
    -*
    -*/
    -QString loadCalibrationVariables(const QString &config)  {
    -
    -
    -
    -  //  UserInterface& ui = Application::GetUserInterface();
    -
    -  FileName calibFile(config);
    -  if ( config.contains("?") ) calibFile = calibFile.highestVersion();
    -
    -  // Pvl configFile;
    -  g_configFile.read(calibFile.expanded());
    -
    -  // Load the groups
    -  PvlGroup &Bias = g_configFile.findGroup("Bias");
    -  PvlGroup &DarkCurrent = g_configFile.findGroup("DarkCurrent");
    -  PvlGroup &Smear = g_configFile.findGroup("SmearRemoval");
    -  PvlGroup &solar = g_configFile.findGroup("SOLARFLUX");
    -  PvlGroup &linearity = g_configFile.findGroup("Linearity");
    -  // PvlGroup &iof = g_configFile.findGroup("RAD");
    -
    -  // Load Smear Removal Variables
    -  g_Tvct = Smear["Tvct"];
    -
    -
    -
    -  // Load DarkCurrent variables and calculate the dark current
    -  g_d0 = DarkCurrent["D"][0].toDouble();
    -  g_d1 = DarkCurrent["D"][1].toDouble();
    -  double CCDTemp(0.0);
    -
    -  switch (g_instrument) {
    -    case InstrumentType::ONCT:
    -      CCDTemp = g_CCD_T_temperature;
    -    break;
    -    case InstrumentType::ONCW1:
    -      CCDTemp = g_CCD_W1_temperature;
    -    break;
    -    case InstrumentType::ONCW2:
    -      CCDTemp = g_CCD_W2_temperature;
    -    break;
    -    default:
    -      CCDTemp = g_CCD_T_temperature;
    -  }
    -
    -   g_darkCurrent = g_texp*exp(0.10*CCDTemp+0.52);
    -
    -  // Load Bias variables
    -  g_b0 = Bias["B"][0].toDouble();
    -  g_b1 = Bias["B"][1].toDouble();
    -  g_b2 = Bias["B"][2].toDouble();
    -  g_bae0 = Bias["B_AE"][0].toDouble();
    -  g_bae1 = Bias["B_AE"][1].toDouble();
    -
    -
    -
    -  // Compute BIAS correction factor (it's a constant so do it once!)
    -  g_bias = g_b0+g_b1*g_CCD_T_temperature+g_b2*g_ECT_T_temperature;
    -  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //correction factor
    -  qDebug() << "Bias: " << g_bias;
    -
    -  // Load the Solar Flux for the specific filter
    -  g_solarFlux = solar[g_filter.toLower()];
    -
    -  //Load the linearity variables
    -  g_L0 = linearity["L"][0].toDouble();
    -  g_L1 = linearity["L"][1].toDouble();
    -  g_L2 = linearity["L"][2].toDouble();
    -
    -
    -  // radiance = g_v_standard * g_iofScale
    -  // iof      = radiance * pi *dist_au^2
    -  // g_iofScale   = iof[g_filter];
    -
    -  return ( calibFile.original() );
    -}
    -
    -
    -/**
    -* @brief Apply radiometric correction to each line of an AMICA image.
    -* @author 2016-03-30 Kris Becker
    -* @param in   Raw image and flat field
    -* @param out  Radometrically corrected image
    -* @internal
    -*   @history 2017-07-2017 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    -*/
    -void Calibrate(vector& in, vector& out) {
    -
    -  Buffer& imageIn   = *in[0];
    -  Buffer& flatField = *in[1];
    -  Buffer& imageOut  = *out[0];
    -
    -  int pixelsToNull = 0;
    -
    -  // Note that is isn't currently tested, as we do not have a test with a hayabusa2 image that
    -  // has been on-board cropped.
    -  int currentSample = imageIn.Sample();
    -  int alphaSample = alpha->AlphaSample(currentSample);
    -
    -  if ( (alphaSample <= pixelsToNull)  || (alphaSample >= (1024 - pixelsToNull ) ) ) {
    -
    -    for (int i = 0; i < imageIn.size(); i++ ) {
    -      imageOut[i] = Isis::Null;
    -    }
    -    return;
    -  }
    -
    -  // Iterate over the line space
    -  for (int i = 0; i < imageIn.size(); i++) { 
    -    imageOut[i] = imageIn[i]*pow(2.0,12-g_bitDepth);
    -
    -
    -
    -    // Check for special pixel in input image and pass through
    -    if ( IsSpecial(imageOut[i]) ) {
    -      imageOut[i] = imageIn[i];
    -      continue;
    -    }
    -
    -    // Apply compression factor here to raise LOSSY dns to proper response
    -    imageOut[i] *= g_compfactor;
    -
    -
    -    // 1) BIAS Removal - Only needed if not on-board corrected
    -
    -
    -    if ( !g_onBoardSmearCorrection ) {
    -
    -
    -      if ( (imageOut[i] - g_bias) <= 0.0) {
    -        imageOut[i] = Null;
    -        continue;
    -      }
    -      else {
    -        imageOut[i] = imageOut[i] - g_bias;
    -      }
    -    }
    -
    -
    -#if 0
    -    double linearCorrection;
    -    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    -    imageOut[i]*=linearCorrection;
    -
    -#endif
    -
    -
    -    // DARK Current
    -    imageOut[i] = imageOut[i] - g_darkCurrent;
    -
    -
    -
    -
    -    // READOUT Smear Removal - Not needed if on-board corrected.  Binning is
    -    //    accounted for in computation of c1 before loop.
    -    // if (nsubImages <= 1) {
    -    //  imageOut[i] = c1*(imageOut[i] - smear);
    -    // }
    -    if (!g_onBoardSmearCorrection) {
    -
    -      double smear = 0;
    -      for (int j=0;j < imageIn.size();j++) {
    -        smear += (imageOut[j]/imageIn.size() );
    -      }
    -      smear*=g_timeRatio;
    -      imageOut[i] = imageOut[i] - smear;
    -
    -      }
    -
    -    //Linearity Correction
    -    //In the SIS this adjustment is made just after the bias, but
    -    //in the Calibration paper it happens just before the flat field correction.
    -
    -#if 0
    -    double linearCorrection;
    -    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    -    qDebug() << "linearCorrection=" << linearCorrection;
    -    imageOut[i]*=linearCorrection;
    - #endif
    -
    -
    -    // FLATFIELD correction
    -    //  Check for any special pixels in the flat field (unlikely)
    -    // If we have only one input cube, that means that we do not have a flat-field (W1/W2).
    -    if (in.size() == 2) {
    -      // Note that our current flat-fields to not have special pixel values.
    -      if ( IsSpecial(flatField[i])  || IsSpecial(imageOut[i]) )
    -      {
    -        imageOut[i] = Isis::Null;
    -        continue;
    -      }
    -      else {
    -        if (flatField[i] != 0) {                 
    -          imageOut[i] /= flatField[i];  
    -        }
    -      }
    -    }
    -
    -    // TODO: once the radiance values are known for each band, we can correctly compute I/F.
    -    // For now, g_iof is 1, so output will be in DNs.
    -    // 7) I/F or Radiance Conversion (or g_iof might = 1, in which case the output will be in DNs)
    -    imageOut[i] *= g_iof;
    -
    -  }
    -
    -
    -  return;
    +  UserInterface &ui = Application::GetUserInterface();
    +  hyb2onccal(ui);
     }
    
    From 4a763700ab04558f49c225b04b608b5b295a7d5d Mon Sep 17 00:00:00 2001
    From: jlaura 
    Date: Wed, 6 Feb 2019 12:47:01 -0700
    Subject: [PATCH 17/24] Updates README with Discourse (#690)
    
    * Updates README with Discourse
    
    * Update README.md
    
    * Update README.md
    ---
     README.md | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/README.md b/README.md
    index b40b5a3ad1..6dc9ae18e1 100644
    --- a/README.md
    +++ b/README.md
    @@ -1,6 +1,7 @@
     # ISIS3
     
     [![Join the chat at https://gitter.im/USGS-Astrogeology/isis3_cmake](https://badges.gitter.im/USGS-Astrogeology/isis3_cmake.svg)](https://gitter.im/USGS-Astrogeology/isis3_cmake?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
    +[![Join the discourse at https://astrodiscuss.usgs.gov](https://img.shields.io/discourse/https/astrodiscuss.usgs.gov/topics.svg?style=flat)](https://astrodiscuss.usgs.gov/)
     
     ## Table of Contents
     
    
    From 32ed751622e2f378002101bb541068d7cbd06be2 Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Thu, 7 Feb 2019 13:09:03 -0700
    Subject: [PATCH 18/24] Changed the Pvl label output for Pvl
     hyb2onc2isis(QString fitsFileName, QString outputCubeFileName,
     CubeAttributeOutput att, QString target)
    
    ---
     isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    index 6f38ae616a..84a0c6f082 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    @@ -256,11 +256,12 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttribute
       // Convert the image data
       importFits.Progress()->SetText("Importing Hayabusa2 image");
        Pvl finalLabel = *(outputCube->label() );
    +   //finalLabel.write("finalLabel.txt");
       importFits.StartProcess();
       importFits.Finalize();
     
     
    -  return outputLabel;
    +  return finalLabel;
     
     
       }
    
    From edeb6bfbb89b10540f2fd2ba5de5cbf6c06458eb Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Thu, 7 Feb 2019 13:34:42 -0700
    Subject: [PATCH 19/24] Added Newton-Rapheson method to Hyb2OncCalUtils.h to
     solve the linearity equation.
    
    ---
     .../apps/hyb2onccal/Hyb2OncCalUtils.h         | 76 +++++++++++++++----
     1 file changed, 60 insertions(+), 16 deletions(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    index e2ef7e6a7a..56979b4af4 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    @@ -103,9 +103,7 @@ static double g_d1(0);
     static double g_darkCurrent(0);
     
     //Linearity correction variables
    -static double g_L0(0);
    -static double g_L1(0);
    -static double g_L2(0);
    +static double g_L[3] = {0.0,0.0,0.0};
     
     // TODO: we do not have the readout time (transfer period) for Hayabusa2 ONC.
     //Smear calculation variables
    @@ -151,6 +149,44 @@ static AlphaCube *alpha(0);
     
     static Pvl g_configFile;
     
    +double linearFun(double Iobs,double x, double g[3]) {
    +  return Iobs - g[0]*x -g[1]*pow(x,2.0) -g[2]*pow(x,3.0);
    +
    +}
    +
    +double dFun(double x, double g[3]) {
    +  return -g[0] - 2*g[1]*x -3*g[2]*pow(x,2.0);
    +
    +}
    +
    +
    +bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double epsilon=1e-6 )  {
    +
    +   double x[2];
    +   double dx = 1.0;
    +   int iter = 0;
    +   int maxIterations=500;
    +   x[0] = x0;
    +   while (dx > epsilon)  {
    +
    +     x[1]=x[0] - linearFun(Iobs,x[0],g)/dFun(x[0],g);
    +     dx = fabs(x[1]-x[0]) ;
    +     x[0]=x[1];
    +     iter++;
    +     if (iter > maxIterations) {
    +
    +       return false;
    +     }
    +   }
    +   result = x[1];
    +   return true;
    +}
    +
    +
    +
    +
    +
    +
     
     /**
     * @brief Apply radiometric correction to each line of an AMICA image.
    @@ -213,12 +249,15 @@ void Calibrate(vector& in, vector& out) {
         }
     
     
    -#if 0
    +    double dn = imageOut[i];
         double linearCorrection;
    -    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    -    imageOut[i]*=linearCorrection;
    +    double result = 1.0;
    +    double x0 = 1.0;
    +    newton_rapheson(imageOut[i],x0, g_L,result );
    +    //linearCorrection = g_L[0]*dn+g_L[1]*pow(dn,2.0)+g_L[2]*pow(dn,3.0);
    +    imageOut[i] = result;
     
    -#endif
    +    //qDebug() << dn << ","<< result;
     
     
         // DARK Current
    @@ -247,12 +286,10 @@ void Calibrate(vector& in, vector& out) {
         //In the SIS this adjustment is made just after the bias, but
         //in the Calibration paper it happens just before the flat field correction.
     
    -#if 0
    -    double linearCorrection;
    -    linearCorrection = g_L0+g_L1*pow(imageOut[i],2.0)+g_L2*pow(imageOut[i],3.0);
    -    qDebug() << "linearCorrection=" << linearCorrection;
    -    imageOut[i]*=linearCorrection;
    - #endif
    +
    +
    +    //imageOut[i]*=linearCorrection;
    +
     
     
         // FLATFIELD correction
    @@ -594,9 +631,9 @@ QString loadCalibrationVariables(const QString &config)  {
       g_solarFlux = solar[g_filter.toLower()];
     
       //Load the linearity variables
    -  g_L0 = linearity["L"][0].toDouble();
    -  g_L1 = linearity["L"][1].toDouble();
    -  g_L2 = linearity["L"][2].toDouble();
    +  g_L[0] = linearity["L"][0].toDouble();
    +  g_L[1] = linearity["L"][1].toDouble();
    +  g_L[2] = linearity["L"][2].toDouble();
     
     
       // radiance = g_v_standard * g_iofScale
    @@ -610,6 +647,13 @@ QString loadCalibrationVariables(const QString &config)  {
     
     
     
    +
    +
    +
    +
    +
    +
    +
     }
     
     #endif
    
    From 1af31c98809163f2d4bd736815d8223ae7b5e41b Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Tue, 12 Feb 2019 15:09:58 -0700
    Subject: [PATCH 20/24] Final push of hayabusa2 changes made to the
     ingestion/calibration applications.
    
    ---
     .../apps/hyb2onc2isis/hyb2onc2isis.cpp        | 11 ++--
     .../apps/hyb2onccal/Hyb2OncCalUtils.h         | 55 +++++++++++++------
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.cpp  |  6 +-
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.xml  |  3 +
     isis/tests/hyb2onc2isisTests.cpp              | 32 +++++++++--
     5 files changed, 75 insertions(+), 32 deletions(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    index 84a0c6f082..3149a103dc 100644
    --- a/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onc2isis/hyb2onc2isis.cpp
    @@ -53,6 +53,7 @@ void hyb2onc2isis(UserInterface &ui) {
     
     Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttributeOutput att, QString target) {
     
    +  Pvl finalPvl;
       ProcessImportFits importFits;
       importFits.setFitsFile(FileName(fitsFileName));
       importFits.setProcessFileStructure(0);
    @@ -138,7 +139,7 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttribute
     
       // Translate the Instrument group
     
    -  FileName transFile(transDir + "hyb2oncInstrument1.trn");
    +  FileName transFile(transDir + "hyb2oncInstrument.trn");
     
       if (updatedKeywords) {
         transFile = transDir+"hyb2oncInstrumentUpdated.trn";
    @@ -255,20 +256,16 @@ Pvl hyb2onc2isis(QString fitsFileName, QString outputCubeFileName, CubeAttribute
     
       // Convert the image data
       importFits.Progress()->SetText("Importing Hayabusa2 image");
    -   Pvl finalLabel = *(outputCube->label() );
    -   //finalLabel.write("finalLabel.txt");
    +
       importFits.StartProcess();
       importFits.Finalize();
     
    -
    -  return finalLabel;
    +  return outputLabel;
     
     
       }
     
     
     
    -
    -
     }
     
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    index 56979b4af4..d68d80d465 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    @@ -149,17 +149,45 @@ static AlphaCube *alpha(0);
     
     static Pvl g_configFile;
     
    +
    +/**
    + * @brief linearFun:  The linear correction function (used by the newton_rapheson method)
    + * @author 2019-02-12  Tyler Wilson
    + * @param Iobs:  The observed intensity
    + * @param x:  The ideal intensity.
    + * @param g:  The vector of empirically derived coefficients for the third-order polynomial
    + * modelling the linear correction (for DN values < 3400 DN)
    + * @return The value of the function at the point x.
    + */
     double linearFun(double Iobs,double x, double g[3]) {
       return Iobs - g[0]*x -g[1]*pow(x,2.0) -g[2]*pow(x,3.0);
     
     }
     
    +/**
    + * @brief dFun:  The first-order derivative of linearFun
    + * @author 2019-02-12  Tyler Wilson
    + * @param x:  The ideal intensity.
    + * @param g:  The vector of empirically derived coefficients for the third-order polynomial
    + * modelling the linear correction (for DN values < 3400 DN)
    + * @return
    + */
     double dFun(double x, double g[3]) {
       return -g[0] - 2*g[1]*x -3*g[2]*pow(x,2.0);
     
     }
     
    -
    +/**
    + * @brief newton_rapheson
    + * @author 2019-02-12 Tyler Wilson
    + * @param Iobs:  The observed DN intensity
    + * @param x0:  The starting value for the Newton-Rapheson method
    + * @param g:  A vector of the coefficients for the linearity function.  It is a third-order
    + * polynomial.
    + * @param result:  The final approximation of the root of the equation.
    + * @param epsilon:  The tolerance on the final solution.
    + * @return A root of the linearity correction function, centered near the origin.
    + */
     bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double epsilon=1e-6 )  {
     
        double x[2];
    @@ -195,6 +223,7 @@ bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double e
     * @param out  Radometrically corrected image
     * @internal
     *   @history 2017-07-2017 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    +*   @history 2019-02-12 Tyler Wilson - Modified to support new calibration settings/formulas.
     */
     void Calibrate(vector& in, vector& out) {
     
    @@ -231,6 +260,7 @@ void Calibrate(vector& in, vector& out) {
     
         // Apply compression factor here to raise LOSSY dns to proper response
         imageOut[i] *= g_compfactor;
    +    qDebug() << "Compfactor:  "  <& in, vector& out) {
         }
     
     
    -    double dn = imageOut[i];
    -    double linearCorrection;
    +    double dn = imageOut[i];    
         double result = 1.0;
         double x0 = 1.0;
    -    newton_rapheson(imageOut[i],x0, g_L,result );
    +    newton_rapheson(dn,x0, g_L,result );
         //linearCorrection = g_L[0]*dn+g_L[1]*pow(dn,2.0)+g_L[2]*pow(dn,3.0);
         imageOut[i] = result;
     
    @@ -271,6 +300,8 @@ void Calibrate(vector& in, vector& out) {
         // if (nsubImages <= 1) {
         //  imageOut[i] = c1*(imageOut[i] - smear);
         // }
    +
    +
         if (!g_onBoardSmearCorrection) {
     
           double smear = 0;
    @@ -281,7 +312,6 @@ void Calibrate(vector& in, vector& out) {
           imageOut[i] = imageOut[i] - smear;
     
           }
    -
         //Linearity Correction
         //In the SIS this adjustment is made just after the bias, but
         //in the Calibration paper it happens just before the flat field correction.
    @@ -312,7 +342,9 @@ void Calibrate(vector& in, vector& out) {
         // TODO: once the radiance values are known for each band, we can correctly compute I/F.
         // For now, g_iof is 1, so output will be in DNs.
         // 7) I/F or Radiance Conversion (or g_iof might = 1, in which case the output will be in DNs)
    -    imageOut[i] *= g_iof;
    +    imageOut[i] *=g_iof;
    +
    +
     
       }
     
    @@ -548,6 +580,7 @@ void  translate(Cube *flatField,double *transform, QString fname) {
     * @return FileName Path and name of flat file file
     * @internal
     *   @history 2017-07-27 Ian Humphrey & Kaj Williams - Adapted from amicacal.
    +*   @history 2019-02-12 Tyler Wilson - Modified to support new calibration settings/formulas.
     */
     FileName DetermineFlatFieldFile(const QString &filter) {
     
    @@ -625,7 +658,6 @@ QString loadCalibrationVariables(const QString &config)  {
       // Compute BIAS correction factor (it's a constant so do it once!)
       g_bias = g_b0+g_b1*g_CCD_T_temperature+g_b2*g_ECT_T_temperature;
       g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //correction factor
    -  qDebug() << "Bias: " << g_bias;
     
       // Load the Solar Flux for the specific filter
       g_solarFlux = solar[g_filter.toLower()];
    @@ -645,15 +677,6 @@ QString loadCalibrationVariables(const QString &config)  {
     
     
     
    -
    -
    -
    -
    -
    -
    -
    -
    -
     }
     
     #endif
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    index 145fa318df..ddd0ae8047 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    @@ -151,7 +151,7 @@ void hyb2onccal(UserInterface &ui) {
     
       try {
         g_AEtemperature = inst["ONCAETemperature"][0].toDouble();
    -    qDebug() << "g_AEtemperature:  " << g_AEtemperature;
    +
       }
       catch(IException &e) {
         QString msg = "Unable to read [ONCAETemperature] keyword in the Instrument group "
    @@ -162,7 +162,7 @@ void hyb2onccal(UserInterface &ui) {
     
       try {
         g_CCD_T_temperature = inst["ONCTCCDTemperature"][0].toDouble();
    -    qDebug() << "g_CCD_T_Temperature:  " << g_CCD_T_temperature;
    +
       }
       catch(IException &e) {
         QString msg = "Unable to read [ONCTCCDTemperature] keyword in the Instrument group "
    @@ -172,7 +172,7 @@ void hyb2onccal(UserInterface &ui) {
     
       try {
         g_ECT_T_temperature = inst["ONCTElectricCircuitTemperature"][0].toDouble();
    -    qDebug() << "g_ECT_T_temperature: " << g_ECT_T_temperature;
    +
       }
       catch(IException &e) {
         QString msg = "Unable to read [ONCTElectricCircuitTemperature] keyword in the Instrument group "
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    index 0a60b43555..cb52834de3 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    @@ -270,6 +270,9 @@ values for each band for Hayabusa2 ONC.
         
           Original version. Adapted from amicacal.
         
    +    
    +      Modified version to handle the updated calibration values/formulas.
    +    
       
     
       
    diff --git a/isis/tests/hyb2onc2isisTests.cpp b/isis/tests/hyb2onc2isisTests.cpp
    index 5e1b213fc6..5e7439429d 100644
    --- a/isis/tests/hyb2onc2isisTests.cpp
    +++ b/isis/tests/hyb2onc2isisTests.cpp
    @@ -12,18 +12,28 @@
     #include 
     
     #include 
    -//#include "gmock/gmock.h"
    +#include "gmock/gmock.h"
     
     using namespace Isis;
     using namespace std;
     
     
    -//QString testDataPath("/usgs/cpkgs/isis3/testData/isis/src");
    +class hyb2onc2isis_PvlComparison : public ::testing::Test {
    +  protected:
    +    Pvl finalPvl;
    +    QString testDataPath;
     
    -QString testDataPath=("/scratch/isis3hayabusa2/tsts");
    +    void SetUp() override {
    +     testDataPath="/scratch/isis3hayabusa2/tsts";
    +     //"/usgs/cpkgs/isis3/testData/isis/src"
    +    }
    +};
     
     
    -TEST(hyb2onc2isis,w1) {
    +
    +
    +
    +TEST_F(hyb2onc2isis_PvlComparison,w1) {
     
       //QString w1Fits(testDataPath+"/hayabusa2/apps/hyb2onc2isis/tsts/w1/input/hyb2_onc_20151204_041027_w1f_l2a.fit");
       QString w1Fits=(testDataPath+"/w1/input/hyb2_onc_20151204_041027_w1f_l2a.fit");
    @@ -31,11 +41,18 @@ TEST(hyb2onc2isis,w1) {
     
       CubeAttributeOutput att;
       att.addAttribute("real");
    -  Pvl outputLabel = hyb2onc2isis(w1Fits, outputCube,att);
    +
    +
    +  finalPvl = hyb2onc2isis(w1Fits, outputCube,att);
    +
    +
     
     
       ofstream w1pvl;
    -  w1pvl << outputLabel;
    +  finalPvl.write("finalLabel.txt");
    +
    +  w1pvl << finalPvl;
    +
     
       ifstream truthpvl(testDataPath.toStdString()+"/w1/truth/labels.pvl");
       stringstream buffer;
    @@ -52,6 +69,9 @@ TEST(hyb2onc2isis,w1) {
       remove("temp.cub");
     
     
    +  //cout << "w1pvlstr:" << w1pvlstr;
    +  //cout << "********************************************************";
    +  //cout  << "truthpvlstr:" << truthpvlstr;
       EXPECT_EQ(w1pvlstr,truthpvlstr);
     
     }
    
    From 590ad485b595fbde1ae889f22776aaa4b6f36f6e Mon Sep 17 00:00:00 2001
    From: Tyler Wilson 
    Date: Sun, 3 Mar 2019 21:34:23 -0700
    Subject: [PATCH 21/24] Added I/F calibration step.  Cleaned up code base and
     worked on the documentation.  The documentation will need to be corrected
     before this is merged into dev.
    
    ---
     .../apps/hyb2onccal/Hyb2OncCalUtils.h         | 167 ++--------------
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.cpp  |  56 +++---
     .../hayabusa2/apps/hyb2onccal/hyb2onccal.xml  | 179 ++----------------
     3 files changed, 64 insertions(+), 338 deletions(-)
    
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    index 98d215835a..79320a5762 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/Hyb2OncCalUtils.h
    @@ -120,14 +120,12 @@ static double g_compfactor(1.0);  // Default if OutputMode = LOSS-LESS; 16.0 for
     static QString g_iofCorrection("IOF");  //!< Is I/F correction to be applied?
     
     //  I/F variables
    -static double g_solarDist(1.0);  /**< Distance from the Sun to the target body
    -(used to calculate g_iof) */
    -static double g_iof(1.0);        //!< I/F conversion value
    +
     static double g_iofScale(1.0);
     static double g_solarFlux(1.0);  //!< The solar flux (used to calculate g_iof).
    -// TODO: we do not have this conversion factor for Hayabusa 2 ONC.
    -static double g_v_standard(1.0);
    -// static double g_v_standard(3.42E-3);//!< Base conversion for all filters (Tbl. 9)
    +static double g_sensitivity(1.0);
    +static double g_effectiveBandwidth(1.0);
    +
     
     namespace Isis {
     
    @@ -212,9 +210,8 @@ bool newton_rapheson(double Iobs,double x0, double g[3],double &result, double e
     }
     
     
    -
     /**
    -* @brief Apply radiometric correction to each line of an AMICA image.
    +* @brief Apply radiometric correction to each line of a Hayabusa2 image.
     * @author 2016-03-30 Kris Becker
     * @param in   Raw image and flat field
     * @param out  Radometrically corrected image
    @@ -247,8 +244,6 @@ void Calibrate(vector& in, vector& out) {
       for (int i = 0; i < imageIn.size(); i++) {
         imageOut[i] = imageIn[i]*pow(2.0,12-g_bitDepth);
     
    -
    -
         // Check for special pixel in input image and pass through
         if ( IsSpecial(imageOut[i]) ) {
           imageOut[i] = imageIn[i];
    @@ -256,13 +251,10 @@ void Calibrate(vector& in, vector& out) {
         }
     
         // Apply compression factor here to raise LOSSY dns to proper response
    -    imageOut[i] *= g_compfactor;
    -    qDebug() << "Compfactor:  "  <& in, vector& out) {
             continue;
           }
           else {
    +
             imageOut[i] = imageOut[i] - g_bias;
           }
         }
     
    -
         double dn = imageOut[i];    
         double result = 1.0;
         double x0 = 1.0;
    -    newton_rapheson(dn,x0, g_L,result );
    -    //linearCorrection = g_L[0]*dn+g_L[1]*pow(dn,2.0)+g_L[2]*pow(dn,3.0);
    +    newton_rapheson(dn,x0, g_L,result );   
         imageOut[i] = result;
     
    -    //qDebug() << dn << ","<< result;
    -
    -
         // DARK Current
    -    imageOut[i] = imageOut[i] - g_darkCurrent;
    -
    -
    -
    -
    -    // READOUT Smear Removal - Not needed if on-board corrected.  Binning is
    -    //    accounted for in computation of c1 before loop.
    -    // if (nsubImages <= 1) {
    -    //  imageOut[i] = c1*(imageOut[i] - smear);
    -    // }
    +    imageOut[i] = imageOut[i] - g_darkCurrent;    
     
     
    +    //Smear correction
         if (!g_onBoardSmearCorrection) {
     
           double smear = 0;
    @@ -309,9 +289,7 @@ void Calibrate(vector& in, vector& out) {
           imageOut[i] = imageOut[i] - smear;
     
           }
    -    //Linearity Correction
    -    //In the SIS this adjustment is made just after the bias, but
    -    //in the Calibration paper it happens just before the flat field correction.
    +
     
     
         // FLATFIELD correction
    @@ -326,18 +304,11 @@ void Calibrate(vector& in, vector& out) {
           }
           else {
             if (flatField[i] != 0) {
    -          imageOut[i] /= flatField[i];
    +          imageOut[i] /= (flatField[i]*g_sensitivity*g_texp);
             }
           }
         }
     
    -    // TODO: once the radiance values are known for each band, we can correctly compute I/F.
    -    // For now, g_iof is 1, so output will be in DNs.
    -    // 7) I/F or Radiance Conversion (or g_iof might = 1, in which case the output will be in DNs)
    -    imageOut[i] *=g_iof;
    -
    -
    -
       }
     
     
    @@ -346,105 +317,7 @@ void Calibrate(vector& in, vector& out) {
     
     
     
    -/**
    - * @brief Load required NAIF kernels required for timing needs.
    - *
    - * This method maintains the loading of kernels for HAYABUSA timing and
    - * planetary body ephemerides to support time and relative positions of planet
    - * bodies.
    - */
    -/* Helper function for sunDistanceAu, don't need this until we have radiance calibration
    -   parameters for Hayabusa2 ONC-T filters to calculate radiance and I/F
    -static void loadNaifTiming() {
    -  static bool naifLoaded = false;
    -  if (!naifLoaded) {
    -
    -//  Load the NAIF kernels to determine timing data
    -    Isis::FileName leapseconds("$base/kernels/lsk/naif????.tls");
    -    leapseconds = leapseconds.highestVersion();
    -    Isis::FileName sclk("$hayabusa2/kernels/sclk/hyb2_20141203-20161231_v01.tsc");    
    -    Isis::FileName pck1("$hayabusa2/kernels/tspk/de430.bsp");
    -    Isis::FileName pck2("$hayabusa2/kernels/tspk/jup329.bsp");
    -    Isis::FileName pck3("$hayabusa2/kernels/tspk/sat375.bsp");
    -    Isis::FileName pck4("$hayabusa2/kernels/spk/hyb2_20141203-20141214_0001m_final_ver1.oem.bsp");
    -    Isis::FileName pck5("$hayabusa2/kernels/spk/hyb2_20141203-20151231_0001h_final_ver1.oem.bsp");
    -    Isis::FileName pck6("$hayabusa2/kernels/spk/hyb2_20151123-20151213_0001m_final_ver1.oem.bsp");
    -
    -//  Load the kernels
    -    QString leapsecondsName(leapseconds.expanded());
    -    QString sclkName(sclk.expanded());
    -
    -    QString pckName1(pck1.expanded());
    -    QString pckName2(pck2.expanded());
    -    QString pckName3(pck3.expanded());
    -    QString pckName4(pck4.expanded());
    -    QString pckName5(pck5.expanded());
    -    QString pckName6(pck6.expanded());
    -
    -    furnsh_c(leapsecondsName.toLatin1().data());
    -    furnsh_c(sclkName.toLatin1().data());
    -
    -    furnsh_c(pckName1.toLatin1().data());
    -    furnsh_c(pckName2.toLatin1().data());
    -    furnsh_c(pckName3.toLatin1().data());
    -    furnsh_c(pckName4.toLatin1().data());
    -    furnsh_c(pckName5.toLatin1().data());
    -    furnsh_c(pckName6.toLatin1().data());
    -
    -
    -//  Ensure it is loaded only once
    -    naifLoaded = true;
    -  }
    -  return;
    -}
    -*/
    -
    -
    -/**
    - * @brief Computes the distance from the Sun to the observed body.
    - *
    - * This method requires the appropriate NAIK kernels to be loaded that
    - * provides instrument time support, leap seconds and planet body ephemeris.
    - *  
    - * @return @b double Distance in AU between Sun and observed body.
    - */
    -/* commented out until we have radiance values (RAD/IOF group in calibration trn) for Hayabusa2.
    - static bool sunDistanceAU(const QString &scStartTime,
    -                          const QString &target,
    -                          double &sunDist) {
    -
    -  //  Ensure NAIF kernels are loaded
    -  loadNaifTiming();
    -  sunDist = 1.0;
    -
    -  //  Determine if the target is a valid NAIF target
    -  SpiceInt tcode;
    -  SpiceBoolean found;
    -  bodn2c_c(target.toLatin1().data(), &tcode, &found);
    -
    -  if (!found) return (false);
    -
    -  //  Convert starttime to et
    -  double obsStartTime;
    -  scs2e_c(-37, scStartTime.toLatin1().data(), &obsStartTime);
    -
    -  //  Get the vector from target to sun and determine its length
    -  double sunv[3];
    -  double lt;
    -  spkpos_c(target.toLatin1().data(), obsStartTime, "J2000", "LT+S", "sun",
    -                  sunv, <);
    -  NaifStatus::CheckErrors();
     
    -  double sunkm = vnorm_c(sunv);
    -
    -
    -  //  Return in AU units
    -  sunDist = sunkm / 1.49597870691E8;
    -
    -  //cout << "sunDist = " << sunDist << endl;
    -  return (true);
    -}
    -*/
     
     
     /**
    @@ -578,8 +451,10 @@ FileName DetermineFlatFieldFile(const QString &filter) {
     
       QString fileName = "$hayabusa2/calibration/flatfield/";
       // FileName consists of binned/notbinned, camera, and filter
    -  fileName += "flat_" + filter.toLower() + ".cub";
    +  fileName += "flat_" + filter.toLower() + "_norm.cub";
    +
       FileName final(fileName);
    +
       return final;
     }
     
    @@ -609,6 +484,8 @@ QString loadCalibrationVariables(const QString &config)  {
       PvlGroup &DarkCurrent = g_configFile.findGroup("DarkCurrent");
       PvlGroup &Smear = g_configFile.findGroup("SmearRemoval");
       PvlGroup &solar = g_configFile.findGroup("SOLARFLUX");
    +  PvlGroup &sensitivity = g_configFile.findGroup("SENSITIVITYFACTOR");
    +  PvlGroup & effectiveBW = g_configFile.findGroup("EFFECTIVEBW");
       PvlGroup &linearity = g_configFile.findGroup("Linearity");
       // PvlGroup &iof = g_configFile.findGroup("RAD");
     
    @@ -649,27 +526,23 @@ QString loadCalibrationVariables(const QString &config)  {
     
       // Compute BIAS correction factor (it's a constant so do it once!)
       g_bias = g_b0+g_b1*g_CCD_T_temperature+g_b2*g_ECT_T_temperature;
    -  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //correction factor
    +  //double correction_factor = (g_bae0 + g_bae1*g_AEtemperature);
    +  g_bias *= (g_bae0 + g_bae1*g_AEtemperature); //bias correction factor
     
       // Load the Solar Flux for the specific filter
       g_solarFlux = solar[g_filter.toLower()];
    +  g_sensitivity = sensitivity[g_filter.toLower()];
    +  g_effectiveBandwidth = effectiveBW[g_filter.toLower()];
     
       //Load the linearity variables
       g_L[0] = linearity["L"][0].toDouble();
       g_L[1] = linearity["L"][1].toDouble();
       g_L[2] = linearity["L"][2].toDouble();
     
    -
    -
    -  // radiance = g_v_standard * g_iofScale
    -  // iof      = radiance * pi *dist_au^2
    -  // g_iofScale   = iof[g_filter];
    -
       return ( calibFile.original() );
     }
     
     
    -
     }
     
     #endif
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    index ddd0ae8047..a6a6778e84 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.cpp
    @@ -39,9 +39,6 @@
     using namespace std;
     
     
    -//void Calibrate(vector& in, vector& out);
    -
    -//QString loadCalibrationVariables(const QString &config);
     
     
     
    @@ -126,7 +123,6 @@ void hyb2onccal(UserInterface &ui) {
       catch (IException &e) {
         QString msg = "Unable to read [BitDepth] keyword in the Instrument group "
         "from input file [" + icube->fileName() + "]";
    -    //qDebug() << msg;
         g_bitDepth = 12;
     
       }
    @@ -208,11 +204,16 @@ void hyb2onccal(UserInterface &ui) {
       if (smearCorrection=="ONBOARD") {
         g_onBoardSmearCorrection=true;
       }
    +  else {
    +      qDebug() << icube->fileName();
    +
    +  }
     
       QString compmode = inst["Compression"];
       // TODO: verify that the compression factor/scale is actually 16 for compressed Hayabusa2 images.
       g_compfactor = ( "lossy" == compmode.toLower() ) ? 16.0 : 1.0;
     
    +
       QString target = inst["TargetName"];
       g_target = target;
     
    @@ -273,14 +274,12 @@ void hyb2onccal(UserInterface &ui) {
     
           Cube *flatOriginal = new Cube(flatfile.expanded() );
     
    -      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
     
           double alphaStartSample = alphaCube["AlphaStartingSample"][0].toDouble();
           double alphaStartLine = alphaCube["AlphaStartingLine"][0].toDouble();
           double alphaEndSample = alphaCube["AlphaEndingSample"][0].toDouble();
           double alphaEndLine = alphaCube["AlphaEndingLine"][0].toDouble();
     
    -      //int transform[5] = {binning,startSample,startLine,lastSample,lastLine};
           double transform[5] = {(double)binning,alphaStartSample,alphaStartLine,alphaEndSample,alphaEndLine};
     
           // Translates and scales the flatfield image.  Scaling
    @@ -302,13 +301,14 @@ void hyb2onccal(UserInterface &ui) {
     
     
       Cube *ocube  = p.SetOutputCube("TO");
    -  //QString fname = ocube->fileName();
    +
     
       QString calfile = loadCalibrationVariables(ui.GetAsString("CONFIG"));
     
    +
    +
       g_timeRatio = g_Tvct/(g_texp + g_Tvct);
     
    -  g_iof = 1.0;  // Units of DN
     
       QString g_units = "DN";
       // if ( "radiance" == g_iofCorrection.toLower() ) {
    @@ -350,7 +350,10 @@ void hyb2onccal(UserInterface &ui) {
       calibrationLog.addKeyword(PvlKeyword("CalibrationFile", calfile));
       calibrationLog.addKeyword(PvlKeyword("FlatFieldFile", flatfile.originalPath()
       + "/" + flatfile.name()));
    -  calibrationLog.addKeyword(PvlKeyword("CompressionFactor", toString(g_compfactor, 2)));
    +
    +  PvlKeyword sensitivityFactor("SensitivityFactor");
    +  sensitivityFactor.addValue(toString(g_sensitivity,16));
    +  calibrationLog.addKeyword(sensitivityFactor);
     
       // Parameters
       PvlKeyword bn("Bias_Bn");
    @@ -362,18 +365,7 @@ void hyb2onccal(UserInterface &ui) {
       PvlKeyword bnae("Bias_AECorrection");
       bnae.addValue(toString(g_bae0, 8));
       bnae.addValue(toString(g_bae1, 8));
    -  calibrationLog.addKeyword(bnae);
    -
    -#if 0
    -  PvlKeyword linearityCoefs("Linearity");
    -  linearityCoefs.addValue(toString(g_L0,8));
    -  linearityCoefs.addValue(toString(g_L1,8));
    -  linearityCoefs.addValue(toString(g_L2,8));
    -  calibrationLog.addKeyword(linearityCoefs);
    -
    -#endif
    -
    -
    +  calibrationLog.addKeyword(bnae);  
       calibrationLog.addKeyword(PvlKeyword("Bias_AETemp", toString(g_AEtemperature, 16)));
     
     
    @@ -400,13 +392,27 @@ void hyb2onccal(UserInterface &ui) {
       calibrationLog.addKeyword(PvlKeyword("Smear_texp", toString(g_texp, 16)));
     
       calibrationLog.addKeyword(PvlKeyword("CalibrationUnits", g_iofCorrection));
    -  calibrationLog.addKeyword(PvlKeyword("RadianceStandard", toString(g_v_standard, 16)));
    +
       calibrationLog.addKeyword(PvlKeyword("RadianceScaleFactor", toString(g_iofScale, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("SolarDistance", toString(g_solarDist, 16), "AU"));
    -  calibrationLog.addKeyword(PvlKeyword("SolarFlux", toString(g_solarFlux, 16)));
    -  calibrationLog.addKeyword(PvlKeyword("IOFFactor", toString(g_iof, 16)));
    +  calibrationLog.addKeyword(PvlKeyword("SolarFlux", toString(g_solarFlux, 16)));  
       calibrationLog.addKeyword(PvlKeyword("Units", g_units));
     
    +  PvlKeyword linearityCoefs("LinearityCoefficients");
    +  linearityCoefs.addValue(toString(g_L[0],16));
    +  linearityCoefs.addValue(toString(g_L[1],16));
    +  linearityCoefs.addValue(toString(g_L[2],16));
    +  calibrationLog.addKeyword(linearityCoefs);
    +
    +  PvlKeyword darkCurrentCoefs("DarkCurrentCoefficients");
    +  darkCurrentCoefs.addValue(toString(g_d0,16));
    +  darkCurrentCoefs.addValue(toString(g_d1,16));
    +  calibrationLog.addKeyword(darkCurrentCoefs);
    +
    +  PvlKeyword darkCurrent("DarkCurrent");
    +  darkCurrent.addValue(toString(g_darkCurrent,16));
    +  calibrationLog.addKeyword(darkCurrent);
    +
    +
       // Write Calibration group to output file
       ocube->putGroup(calibrationLog);
       Application::Log(calibrationLog);
    diff --git a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    index cb52834de3..eb0d72d00e 100644
    --- a/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    +++ b/isis/src/hayabusa2/apps/hyb2onccal/hyb2onccal.xml
    @@ -1,7 +1,7 @@
     
     
     
    -
       
         Calibrates Hayabusa 2 ONC-T images. Calibration includes bias and dark current correction as
    @@ -66,91 +66,6 @@ xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Applica
     
         
       

    - - -

    Step 2: Flat-field correction:

    Performs a correction for pixel-to-pixel variation in CCD response and vignetting @@ -162,86 +77,8 @@ xsi:noNamespaceSchemaLocation="http://isis.astrogeology.usgs.gov/Schemas/Applica pixel in the flat-field image.

    - - -

    -

    Notes

    -
      -
    1. - Smear correction is not currently provided, as we do not have the readout time - (charge-transfer period) for the instrument. -
    2. -
    3. - Similarly, since no radiance values could be found for the instrument filters, the output - cannot be correctly converted to radiance or I/F. -
    4. -
    5. -
    6. -
    -

    References:

    @@ -249,6 +86,13 @@ values for each band for Hayabusa2 ONC.
  11. S. Kameda et al. "Preflight Calibration Test Results for Optical Navigation Camera Telescope (ONC-T) Onboard the Hayabusa2 Spacecraft". Space Sci Rev (2017) 208:17-31.
  12. +
  13. E. Tatsumi et al. "Updated Inflight Calibration of Hayabusa2’s Optical Navigation Camera (ONC) for + Scientific Observations during the Cruise Phase". + https://arxiv.org/abs/1810.11065 [astro-ph.IM] 25 Oct, 2018. +
  14. +
  15. H. Suzuki et al. "Initial inflight calibration for Hayabusa2 optical navigation camera + (ONC) for science observations of asteroid Ryugu". + Icarus. 300. 10.1016/j.icarus.2017.09.011

@@ -318,11 +162,14 @@ values for each band for Hayabusa2 ONC. the parameters as needed.
*.trn - + /scratch/isis3data/hayabusa2/calibration/onc/hyb2oncCalibration????.trn --> + /usgs/cpkgs/isis3/datalocal/hayabusa2/calibration/onc/hyb2oncCalibration????.trn + +