USGS

Isis 3.0 Application Source Code Reference

Home

lrowac2isis.cpp

Go to the documentation of this file.
00001 #include "Isis.h"
00002 
00003 #include <cstdio>
00004 #include <QString>
00005 
00006 #include <QRegExp>
00007 
00008 #include "ProcessImportPds.h"
00009 #include "LineManager.h"
00010 #include "OriginalLabel.h"
00011 #include "Brick.h"
00012 #include "History.h"
00013 #include "Stretch.h"
00014 
00015 using namespace std;
00016 using namespace Isis;
00017 
00018 vector<Cube *> outputCubes;
00019 vector<int> frameletLines;
00020 void separateFramelets(Buffer &in);
00021 void writeNullsToFile();
00022 void TranslateLabels(Pvl &pdsLab, Pvl &isis3VisEven, Pvl &isis3VisOdd,
00023                      Pvl &isis3UvEven, Pvl &isis3UvOdd);
00024 void ValidateInputLabels(Pvl &pdsLab);
00025 
00026 std::vector<int> padding;
00027 int colorOffset = 0;
00028 int inputCubeLines = 0;
00029 
00030 // Output UV Files
00031 Cube *uveven = NULL;
00032 Cube *uvodd = NULL;
00033 
00034 // Output VIS Files
00035 Cube *viseven = NULL;
00036 Cube *visodd = NULL;
00037 
00038 Stretch lookupTable;
00039 
00040 bool flip = false;
00041 
00042 void IsisMain() {
00043   colorOffset = 0;
00044   frameletLines.clear();
00045   outputCubes.clear();
00046 
00047   uveven = NULL;
00048   uvodd = NULL;
00049   viseven = NULL;
00050   visodd = NULL;
00051 
00052   ProcessImportPds p;
00053   Pvl pdsLab;
00054 
00055   UserInterface &ui = Application::GetUserInterface();
00056   QString fromFile = ui.GetFileName("FROM");
00057 
00058   flip = false;//ui.GetBoolean("FLIP");
00059 
00060   p.SetPdsFile(fromFile, "", pdsLab);
00061   ValidateInputLabels(pdsLab);
00062   inputCubeLines = p.Lines();
00063 
00064   lookupTable = Stretch();
00065 
00066   // read the lut if the option is on
00067   if(ui.GetBoolean("UNLUT") && pdsLab["LRO:LOOKUP_TABLE_TYPE"][0] == "STORED") {
00068     PvlKeyword lutKeyword = pdsLab["LRO:LOOKUP_CONVERSION_TABLE"];
00069 
00070     for(int i = 0; i < lutKeyword.Size(); i ++) {
00071       IString lutPair = lutKeyword[i];
00072       lutPair.ConvertWhiteSpace();
00073       lutPair.Remove("() ");
00074       QString outValueMin = lutPair.Token(" ,").ToQt();
00075       QString outValueMax = lutPair.Token(" ,").ToQt();
00076       lookupTable.AddPair(i, (toDouble(outValueMin) + toDouble(outValueMax)) / 2.0);
00077     }
00078   }
00079 
00080   QString instModeId = pdsLab["INSTRUMENT_MODE_ID"];
00081 
00082   // this will be used to convert num input lines to num output lines,
00083   //   only changed for when both uv and vis exist (varying summing)
00084   double visOutputLineRatio = 1.0;
00085   double uvOutputLineRatio = 1.0;
00086 
00087   int numFilters = 0;
00088   if(ui.GetBoolean("COLOROFFSET")) {
00089     colorOffset = ui.GetInteger("COLOROFFSETSIZE");
00090   }
00091 
00092   // Determine our band information based on
00093   // INSTRUMENT_MODE_ID - FILTER_NUMBER is
00094   // only going to be used for BW images
00095   if(instModeId == "COLOR") {
00096     numFilters = 7;
00097     frameletLines.push_back(4);
00098     frameletLines.push_back(4);
00099     frameletLines.push_back(14);
00100     frameletLines.push_back(14);
00101     frameletLines.push_back(14);
00102     frameletLines.push_back(14);
00103     frameletLines.push_back(14);
00104 
00105     uveven  = new Cube();
00106     uvodd   = new Cube();
00107     viseven = new Cube();
00108     visodd  = new Cube();
00109 
00110     // 14 output lines (1 framelet) from 5vis/2uv lines
00111     visOutputLineRatio = 14.0 / (14.0 * 5.0 + 4.0 * 2.0);
00112 
00113     // 4 output lines (1 framelet) from 5vis/2uv lines
00114     uvOutputLineRatio = 4.0 / (14.0 * 5.0 + 4.0 * 2.0);
00115   }
00116   else if(instModeId == "VIS") {
00117     numFilters = 5;
00118 
00119     frameletLines.push_back(14);
00120     frameletLines.push_back(14);
00121     frameletLines.push_back(14);
00122     frameletLines.push_back(14);
00123     frameletLines.push_back(14);
00124 
00125     viseven = new Cube();
00126     visodd  = new Cube();
00127 
00128     // 14 output lines (1 framelet) from 5vis/2uv lines
00129     visOutputLineRatio = 14.0 / (14.0 * 5.0);
00130   }
00131   else if(instModeId == "UV") {
00132     numFilters = 2;
00133 
00134     frameletLines.push_back(4);
00135     frameletLines.push_back(4);
00136 
00137     uveven = new Cube();
00138     uvodd  = new Cube();
00139 
00140     // 4 output lines (1 framelet) from 2uv lines
00141     uvOutputLineRatio = 4.0 / (4.0 * 2.0);
00142   }
00143   else if(instModeId == "BW") {
00144     numFilters = 1;
00145 
00146     frameletLines.push_back(14);
00147 
00148     viseven = new Cube();
00149     visodd  = new Cube();
00150   }
00151 
00152   padding.resize(numFilters);
00153 
00154 
00155   for(int filter = 0; filter < numFilters; filter++) {
00156     padding[filter] = (colorOffset * frameletLines[filter]) * filter;
00157 
00158     // dont count UV for VIS offsetting
00159     if(instModeId == "COLOR" && filter > 1) {
00160       padding[filter] -= 2 * colorOffset * frameletLines[filter];
00161     }
00162   }
00163 
00164   FileName baseFileName(ui.GetFileName("TO"));
00165 
00166   if(uveven && uvodd) {
00167     // padding[1] is max padding for UV
00168     int numSamples = ((viseven) ? p.Samples() / 4 : p.Samples());
00169     numSamples     = 128; // UV is alway sum 4 so it is 128 samples
00170     int numLines   = (int)(uvOutputLineRatio * inputCubeLines + 0.5) + padding[1];
00171     int numBands   = 2;
00172 
00173     uveven->setDimensions(numSamples, numLines, numBands);
00174     uveven->setPixelType(Isis::Real);
00175 
00176     QString filename = baseFileName.path() + "/" + baseFileName.baseName() + ".uv.even.cub";
00177     uveven->create(filename);
00178 
00179     uvodd->setDimensions(numSamples, numLines, numBands);
00180     uvodd->setPixelType(Isis::Real);
00181 
00182     filename = baseFileName.path() + "/" + baseFileName.baseName() + ".uv.odd.cub";
00183     uvodd->create(filename);
00184   }
00185 
00186   if(viseven && visodd) {
00187     // padding[size-1] is max padding for vis (padding[0] or padding[4] or padding[6])
00188     int numSamples = p.Samples();
00189     int numLines   = (int)(visOutputLineRatio * inputCubeLines + 0.5) + padding[padding.size()-1];
00190     int numBands   = ((uveven) ? padding.size() - 2 : padding.size());
00191 
00192     viseven->setDimensions(numSamples, numLines, numBands);
00193     viseven->setPixelType(Isis::Real);
00194 
00195     QString filename = baseFileName.path() + "/" + baseFileName.baseName() + ".vis.even.cub";
00196     viseven->create(filename);
00197 
00198     visodd->setDimensions(numSamples, numLines, numBands);
00199     visodd->setPixelType(Isis::Real);
00200 
00201     filename = baseFileName.path() + "/" + baseFileName.baseName() + ".vis.odd.cub";
00202     visodd->create(filename);
00203   }
00204 
00205   Pvl isis3VisEvenLab, isis3VisOddLab, isis3UvEvenLab, isis3UvOddLab;
00206   TranslateLabels(pdsLab, isis3VisEvenLab, isis3VisOddLab, isis3UvEvenLab, isis3UvOddLab);
00207 
00208   writeNullsToFile();
00209   p.StartProcess(separateFramelets);
00210   p.EndProcess();
00211 
00212   // Add original labels
00213   OriginalLabel origLabel(pdsLab);
00214 
00215   int numFramelets = padding.size();
00216   PvlKeyword numFrameletsKeyword("NumFramelets", toString(numFramelets));
00217 
00218   if(uveven) {
00219     for(int grp = 0; grp < isis3UvEvenLab.Groups(); grp++) {
00220       uveven->putGroup(isis3UvEvenLab.Group(grp));
00221     }
00222 
00223     History history("IsisCube");
00224     history.AddEntry();
00225     uveven->write(history);
00226     uveven->write(origLabel);
00227 
00228     uveven->close();
00229     delete uveven;
00230     uveven = NULL;
00231   }
00232 
00233   if(uvodd) {
00234     for(int grp = 0; grp < isis3UvOddLab.Groups(); grp++) {
00235       uvodd->putGroup(isis3UvOddLab.Group(grp));
00236     }
00237 
00238     History history("IsisCube");
00239     history.AddEntry();
00240     uvodd->write(history);
00241     uvodd->write(origLabel);
00242 
00243     uvodd->close();
00244     delete uvodd;
00245     uvodd = NULL;
00246   }
00247 
00248   if(viseven) {
00249     for(int grp = 0; grp < isis3VisEvenLab.Groups(); grp++) {
00250       viseven->putGroup(isis3VisEvenLab.Group(grp));
00251     }
00252 
00253     History history("IsisCube");
00254     history.AddEntry();
00255     viseven->write(history);
00256     viseven->write(origLabel);
00257 
00258     viseven->close();
00259     delete viseven;
00260     viseven = NULL;
00261   }
00262 
00263   if(visodd) {
00264     for(int grp = 0; grp < isis3VisOddLab.Groups(); grp++) {
00265       visodd->putGroup(isis3VisOddLab.Group(grp));
00266     }
00267 
00268     History history("IsisCube");
00269     history.AddEntry();
00270     visodd->write(history);
00271     visodd->write(origLabel);
00272 
00273     visodd->close();
00274     delete visodd;
00275     visodd = NULL;
00276   }
00277 }
00278 
00279 /**
00280  * Get the framelet number line is in.
00281  *
00282  * @param line input line number (starting at 1)
00283  * @param even Set to true if even framelet, otherwise false
00284  *
00285  * @return int framelet this line belongs to
00286  */
00287 int getFrameletNumber(int line, int &frameletSetNumber, int &frameletSetOffset,
00288                       int &frameletLineOffset, bool &even) {
00289   int frameletNumber = -1;
00290 
00291   int frameletSetSize = 0;
00292 
00293   // framelet set = one capture of vis/uv data (1 to 7 framelets)
00294   for(unsigned int i = 0; i < frameletLines.size(); i++) {
00295     frameletSetSize += frameletLines[i];
00296   }
00297 
00298   frameletSetNumber = (line - 1) / frameletSetSize;
00299 
00300   // frameletSetNumber is 0-based, but even is 1-based, so logic reversed from
00301   //   what would be intuitive. An odd frameletSetNumber means even framelet.
00302   even = ((frameletSetNumber % 2) == 1);
00303 
00304   // offset into set
00305   frameletSetOffset = line - (frameletSetSize * frameletSetNumber) - 1;
00306 
00307   int offset = frameletSetOffset;
00308   for(unsigned int framelet = 0; frameletNumber < 0; framelet++) {
00309     offset -= frameletLines.at(framelet);
00310 
00311     if(offset < 0) {
00312       frameletNumber = framelet;
00313       frameletLineOffset = offset + frameletLines.at(framelet);
00314     }
00315   }
00316 
00317   return frameletNumber;
00318 }
00319 
00320 //! Separates each of the individual WAC framelets into the right place
00321 void separateFramelets(Buffer &in) {
00322   // this is true if uv is summed and mixed with unsummed vis
00323   bool extractMiddleSamples = false;
00324   // This is the framelet set the line belongs to
00325   int frameletSet = 0;
00326   // this is the offset into the set
00327   int frameletSetOffset = 0;
00328   // this is true if framelet belongs in an even cube
00329   bool even = false;
00330   // line # in current framelet
00331   int frameletLineOffset = 0;
00332   // this is the framelet number the current line belongs in
00333   int framelet = getFrameletNumber(in.Line(), frameletSet, frameletSetOffset, frameletLineOffset, even);
00334   // this is the output file the current line belongs in
00335   Cube *outfile = NULL;
00336 
00337   // uv and vis outputs
00338   if(viseven && uveven) {
00339     if(framelet < 2 && even) {
00340       outfile = uveven;
00341       extractMiddleSamples = true;
00342     }
00343     else if(framelet < 2) {
00344       outfile = uvodd;
00345       extractMiddleSamples = true;
00346     }
00347     else if(even) {
00348       outfile = viseven;
00349     }
00350     else {
00351       outfile = visodd;
00352     }
00353   }
00354   // vis output
00355   else if(viseven) {
00356     if(even) {
00357       outfile = viseven;
00358     }
00359     else {
00360       outfile = visodd;
00361     }
00362   }
00363   // uv output
00364   else {
00365     extractMiddleSamples = true;
00366 
00367     if(even) {
00368       outfile = uveven;
00369     }
00370     else {
00371       outfile = uvodd;
00372     }
00373   }
00374 
00375   // We know our output file now, so get a linemanager for writing
00376   LineManager mgr(*outfile);
00377 
00378   // line is framelet * frameletLineOffset + frameletSetOffset
00379   int outLine = 1;
00380   int outBand = framelet + 1;
00381 
00382   // if both vis & uv on, outLine is a calculation based on the current line
00383   //   being uv or vis and the general calculation (above) does not work
00384   if(viseven && uveven) {
00385     // uv file
00386     if(framelet < 2) {
00387       outLine = frameletSet * 4 + 1 + padding[framelet];
00388     }
00389     // vis file
00390     else {
00391       outLine = frameletSet * 14 + 1 + padding[framelet];
00392       outBand -= 2; // uv is not in vis file
00393     }
00394   }
00395   // only vis on
00396   else if(viseven) {
00397     outLine = frameletSet * 14 + 1 + padding[framelet];
00398   }
00399   // only uv on
00400   else {
00401     outLine = frameletSet * 4 + 1 + padding[framelet];
00402   }
00403 
00404   if(flip) {
00405     outLine = outfile->lineCount() - (outLine - 1);
00406   }
00407 
00408   outLine += frameletLineOffset;
00409 
00410   mgr.SetLine(outLine, outBand);
00411 
00412   if(!extractMiddleSamples) {
00413     for(int i = 0; i < in.size(); i++) {
00414       if(i >= mgr.size()) {
00415         QString msg = "The input file has an unexpected number of samples";
00416         throw IException(IException::Unknown, msg, _FILEINFO_);
00417       }
00418 
00419       mgr[i] = lookupTable.Map(in[i]);
00420     }
00421   }
00422   else {
00423     // read middle of input...
00424     int startSamp = (in.size() / 2) - mgr.size() / 2;
00425     int endSamp = (in.size() / 2) + mgr.size() / 2;
00426 
00427     if(mgr.size() > in.size()) {
00428       QString msg = "Output number of samples calculated is invalid";
00429       throw IException(IException::Unknown, msg, _FILEINFO_);
00430     }
00431 
00432     for(int inputSamp = startSamp; inputSamp < endSamp; inputSamp++) {
00433       mgr[inputSamp - startSamp] = lookupTable.Map(in[inputSamp]);
00434     }
00435   }
00436 
00437   outfile->write(mgr);
00438 }
00439 
00440 /**
00441  * This calculates the output labels for each file, which are only valid if the
00442  * output cubes have been created (uses ns/nl from each file if
00443  * available). Otherwise the label calculated for that particular file is
00444  * incomplete and invalid.
00445  *
00446  * One input file goes to 2 or 4 output file, so let's calculate everything we
00447  * can here.
00448  *
00449  * @param pdsLab Input File Label
00450  * @param isis3VisEven Even vis file output label
00451  * @param isis3VisOdd  Odd vis file output label
00452  * @param isis3UvEven  Even UV file output label
00453  * @param isis3UvOdd   Odd UV file output label
00454  */
00455 void TranslateLabels(Pvl &pdsLab, Pvl &isis3VisEven, Pvl &isis3VisOdd,
00456                      Pvl &isis3UvEven, Pvl &isis3UvOdd) {
00457   // Let's start by running through the generic translations.
00458 
00459   // Get the directory where the translation tables are.
00460   PvlGroup dataDir(Preference::Preferences().FindGroup("DataDirectory"));
00461   QString transDir = (QString) dataDir["Lro"] + "/translations/";
00462 
00463   // Translate the in
00464   FileName transFile(transDir + "lrowacInstrument.trn");
00465   PvlTranslationManager instrumentXlater(pdsLab, transFile.expanded());
00466   instrumentXlater.Auto(isis3VisEven);
00467   instrumentXlater.Auto(isis3VisOdd);
00468   instrumentXlater.Auto(isis3UvEven);
00469   instrumentXlater.Auto(isis3UvOdd);
00470 
00471   // Translate the Archive group
00472   transFile = transDir + "lrowacArchive.trn";
00473   PvlTranslationManager archiveXlater(pdsLab, transFile.expanded());
00474 
00475   archiveXlater.Auto(isis3VisEven);
00476   archiveXlater.Auto(isis3VisOdd);
00477   archiveXlater.Auto(isis3UvEven);
00478   archiveXlater.Auto(isis3UvOdd);
00479 
00480   // Get a couple of user parameters into the instrument groups
00481   UserInterface &ui = Application::GetUserInterface();
00482 
00483   vector<PvlKeyword> genericInstrument;
00484   genericInstrument.push_back(PvlKeyword("DataFlipped", "No"));//(ui.GetBoolean("FLIP")? "Yes" : "No")));
00485 
00486   // color offset doesn't apply to BW mode (single band cubes)
00487   if(colorOffset && viseven && viseven->bandCount() == 1) {
00488     genericInstrument.push_back(PvlKeyword("ColorOffset", 0));
00489   }
00490   else {
00491     genericInstrument.push_back(PvlKeyword("ColorOffset", toString(colorOffset)));
00492   }
00493 
00494   genericInstrument.push_back(PvlKeyword("Decompanded", (ui.GetBoolean("UNLUT") ? "Yes" : "No")));
00495 
00496   // We'll need the instrument groups a lot, get a reference right to them
00497   PvlGroup &visEvenInst = isis3VisEven.FindGroup("Instrument", Pvl::Traverse);
00498   PvlGroup &visOddInst = isis3VisOdd.FindGroup("Instrument", Pvl::Traverse);
00499   PvlGroup &uvEvenInst = isis3UvEven.FindGroup("Instrument", Pvl::Traverse);
00500   PvlGroup &uvOddInst = isis3UvOdd.FindGroup("Instrument", Pvl::Traverse);
00501 
00502   // Add user parameters to the instrument group
00503   for(unsigned int key = 0; key < genericInstrument.size(); key++) {
00504     visEvenInst.AddKeyword(genericInstrument[key]);
00505     visOddInst.AddKeyword(genericInstrument[key]);
00506     uvEvenInst.AddKeyword(genericInstrument[key]);
00507     uvOddInst.AddKeyword(genericInstrument[key]);
00508   }
00509 
00510   // add labels unique to particular files
00511   if(viseven) {
00512     visEvenInst.AddKeyword(PvlKeyword("Framelets", "Even"));
00513     visEvenInst.AddKeyword(PvlKeyword("NumFramelets", toString(viseven->lineCount() / 14)));
00514     visEvenInst.AddKeyword(PvlKeyword("InstrumentId", "WAC-VIS"), Pvl::Replace);
00515     visEvenInst.AddKeyword(PvlKeyword("InstrumentModeId", (QString) pdsLab["INSTRUMENT_MODE_ID"]));
00516   }
00517 
00518   if(visodd) {
00519     visOddInst.AddKeyword(PvlKeyword("Framelets", "Odd"));
00520     visOddInst.AddKeyword(PvlKeyword("NumFramelets", toString(visodd->lineCount() / 14)));
00521     visOddInst.AddKeyword(PvlKeyword("InstrumentId", "WAC-VIS"), Pvl::Replace);
00522     visOddInst.AddKeyword(PvlKeyword("InstrumentModeId", (QString) pdsLab["INSTRUMENT_MODE_ID"]));
00523   }
00524 
00525   // **TEMPORARY. This should be done by a translation table.
00526   // Translate the BandBin group
00527   PvlGroup visBandBin("BandBin");
00528   PvlKeyword visWavelength("Center");
00529   PvlKeyword visFilterNum("FilterNumber");
00530   PvlKeyword visBandwidth("Width");
00531 
00532   if(viseven && viseven->bandCount() == 1) {
00533     visWavelength = pdsLab["CENTER_FILTER_WAVELENGTH"][0];
00534     visFilterNum = pdsLab["FILTER_NUMBER"][0];
00535 
00536     if(pdsLab.HasKeyword("BANDWIDTH")) {
00537       visBandwidth = pdsLab["BANDWIDTH"][0];
00538     }
00539   }
00540   else {
00541     for(int i = 0; i < pdsLab["FILTER_NUMBER"].Size(); i++) {
00542       if(toInt(pdsLab["FILTER_NUMBER"][i]) > 2) {
00543         visWavelength += pdsLab["CENTER_FILTER_WAVELENGTH"][i];
00544         visFilterNum += pdsLab["FILTER_NUMBER"][i];
00545 
00546         if(pdsLab.HasKeyword("BANDWIDTH")) {
00547           visBandwidth += pdsLab["BANDWIDTH"][i];
00548         }
00549       }
00550     }
00551   }
00552 
00553   visBandBin += visFilterNum;
00554   visBandBin += visWavelength;
00555 
00556   if(visBandwidth.Size() != 0) {
00557     visBandBin += visBandwidth;
00558   }
00559 
00560   isis3VisEven += visBandBin;
00561   isis3VisOdd += visBandBin;
00562 
00563   PvlGroup visKerns("Kernels");
00564   visKerns += PvlKeyword("NaifIkCode", "-85621");
00565   isis3VisEven += visKerns;
00566   isis3VisOdd += visKerns;
00567 
00568   if(uveven) {
00569     uvEvenInst.AddKeyword(PvlKeyword("Framelets", "Even"));
00570     uvEvenInst.AddKeyword(PvlKeyword("NumFramelets", toString(uveven->lineCount() / 4)));
00571     uvEvenInst.AddKeyword(PvlKeyword("InstrumentId", "WAC-UV"), Pvl::Replace);
00572     uvEvenInst.AddKeyword(PvlKeyword("InstrumentModeId", (QString) pdsLab["INSTRUMENT_MODE_ID"]));
00573   }
00574 
00575   if(uvodd) {
00576     uvOddInst.AddKeyword(PvlKeyword("Framelets", "Odd"));
00577     uvOddInst.AddKeyword(PvlKeyword("NumFramelets", toString(uvodd->lineCount() / 4)));
00578     uvOddInst.AddKeyword(PvlKeyword("InstrumentId", "WAC-UV"), Pvl::Replace);
00579     uvOddInst.AddKeyword(PvlKeyword("InstrumentModeId", (QString) pdsLab["INSTRUMENT_MODE_ID"]));
00580   }
00581 
00582   // Translate the BandBin group
00583   PvlGroup uvBandBin("BandBin");
00584   PvlKeyword uvWavelength("Center");
00585   PvlKeyword uvFilterNum("FilterNumber");
00586   PvlKeyword uvBandwidth("Width");
00587 
00588   for(int i = 0; i < pdsLab["FILTER_NUMBER"].Size(); i++) {
00589     if(toInt(pdsLab["FILTER_NUMBER"][i]) <= 2) {
00590       uvWavelength += pdsLab["CENTER_FILTER_WAVELENGTH"][i];
00591       uvFilterNum += pdsLab["FILTER_NUMBER"][i];
00592 
00593       if(pdsLab.HasKeyword("BANDWIDTH")) {
00594         uvBandwidth += pdsLab["BANDWIDTH"][i];
00595       }
00596     }
00597   }
00598 
00599   uvBandBin += uvFilterNum;
00600   uvBandBin += uvWavelength;
00601 
00602   if(uvBandwidth.Size() != 0) {
00603     uvBandBin += uvBandwidth;
00604   }
00605 
00606   isis3UvEven += uvBandBin;
00607   isis3UvOdd += uvBandBin;
00608 
00609   PvlGroup uvKerns("Kernels");
00610   uvKerns += PvlKeyword("NaifIkCode", "-85626");
00611 
00612   isis3UvEven += uvKerns;
00613   isis3UvOdd += uvKerns;
00614 }
00615 
00616 /**
00617  * This initializes all of the files will NULL DN's.
00618  *
00619  */
00620 void writeNullsToFile() {
00621   // have output vis files? initialize files with nulls
00622   if(viseven && visodd) {
00623     LineManager evenLineMgr(*viseven);
00624     LineManager oddLineMgr(*visodd);
00625     evenLineMgr.SetLine(1, 1);
00626     oddLineMgr.SetLine(1, 1);
00627 
00628     for(int i = 0; i < evenLineMgr.size(); i++) {
00629       evenLineMgr[i] = Isis::Null;
00630       oddLineMgr[i] = Isis::Null;
00631     }
00632 
00633     while(!evenLineMgr.end()) {
00634       viseven->write(evenLineMgr);
00635       visodd->write(oddLineMgr);
00636       evenLineMgr++;
00637       oddLineMgr++;
00638     }
00639   }
00640 
00641   // have output uv files? initialize files with nulls
00642   if(uveven && uvodd) {
00643     LineManager evenLineMgr(*uveven);
00644     LineManager oddLineMgr(*uvodd);
00645     evenLineMgr.SetLine(1, 1);
00646     oddLineMgr.SetLine(1, 1);
00647 
00648     for(int i = 0; i < evenLineMgr.size(); i++) {
00649       evenLineMgr[i] = Isis::Null;
00650       oddLineMgr[i] = Isis::Null;
00651     }
00652 
00653     while(!evenLineMgr.end()) {
00654       uveven->write(evenLineMgr);
00655       uvodd->write(oddLineMgr);
00656       evenLineMgr++;
00657       oddLineMgr++;
00658     }
00659   }
00660 }
00661 
00662 /**
00663  * This method ensures the integrety of the input labels and that the file is
00664  * exactly as expected.
00665  *
00666  * @param pdsLab PDS Cube Labels
00667  */
00668 void ValidateInputLabels(Pvl &pdsLab) {
00669   try {
00670     // Check known values first to verify they match
00671     PvlKeyword &lut = pdsLab["LRO:LOOKUP_CONVERSION_TABLE"];
00672 
00673     if(lut.Size() != 256) {
00674       QString msg = "Keyword [LRO:LOOKUP_CONVERSION_TABLE] has the wrong number of values";
00675       throw IException(IException::Unknown, msg, _FILEINFO_);
00676     }
00677 
00678     PvlKeyword &missionName = pdsLab["MISSION_NAME"];
00679 
00680     if(missionName.Size() != 1 || missionName[0] != "LUNAR RECONNAISSANCE ORBITER") {
00681       QString msg = "Keyword [MISSION_NAME] does not have a value of [LUNAR RECONNAISSANCER ORBITER]";
00682       throw IException(IException::Unknown, msg, _FILEINFO_);
00683     }
00684 
00685     PvlKeyword &instrumentId = pdsLab["INSTRUMENT_ID"];
00686 
00687     if(instrumentId.Size() != 1 || instrumentId[0] != "LROC") {
00688       QString msg = "Keyword [INSTRUMENT_ID] does not have a value of [LROC]";
00689       throw IException(IException::Unknown, msg, _FILEINFO_);
00690     }
00691 
00692     // Make sure CENTER_FILTER_WAVELENGTH/FILTER_NUMBER makes sense
00693     if(pdsLab["FILTER_NUMBER"].Size() != pdsLab["CENTER_FILTER_WAVELENGTH"].Size()) {
00694       QString msg = "Keywords [FILTER_NUMBER,CENTER_FILTER_WAVELENGTH] must have the same number of values";
00695       throw IException(IException::Unknown, msg, _FILEINFO_);
00696     }
00697 
00698     if(pdsLab["INSTRUMENT_MODE_ID"][0] == "BW" && pdsLab["FILTER_NUMBER"].Size() != 1) {
00699       QString msg = "Keyword [FILTER_NUMBER] must have size 1 if [INSTRUMENT_MODE_ID] is [BW]";
00700       throw IException(IException::Unknown, msg, _FILEINFO_);
00701     }
00702     else if(pdsLab["INSTRUMENT_MODE_ID"][0] == "COLOR" && (pdsLab["FILTER_NUMBER"].Size() < 5
00703             || pdsLab["FILTER_NUMBER"].Size() > 7 || pdsLab["FILTER_NUMBER"].Size() == 6)) {
00704       QString msg = "Keyword [FILTER_NUMBER] must have size 5 or 7 if [INSTRUMENT_MODE_ID] is [COLOR]";
00705       throw IException(IException::Unknown, msg, _FILEINFO_);
00706     }
00707     else if(pdsLab["INSTRUMENT_MODE_ID"][0] == "UV" && pdsLab["FILTER_NUMBER"].Size() != 2) {
00708       QString msg = "Keyword [FILTER_NUMBER] must have size 2 if [INSTRUMENT_MODE_ID] is [UV]";
00709       throw IException(IException::Unknown, msg, _FILEINFO_);
00710     }
00711     else if(pdsLab["INSTRUMENT_MODE_ID"][0] == "VIS" && pdsLab["FILTER_NUMBER"].Size() != 5) {
00712       QString msg = "Keyword [FILTER_NUMBER] must have size 5 if [INSTRUMENT_MODE_ID] is [VIS]";
00713       throw IException(IException::Unknown, msg, _FILEINFO_);
00714     }
00715     else if(pdsLab["INSTRUMENT_MODE_ID"][0] != "BW" && pdsLab["INSTRUMENT_MODE_ID"][0] != "COLOR" &&
00716             pdsLab["INSTRUMENT_MODE_ID"][0] != "UV" && pdsLab["INSTRUMENT_MODE_ID"][0] != "VIS") {
00717       QString msg = "The value of keyword [INSTRUMENT_MODE_ID] is not recognized";
00718       throw IException(IException::Unknown, msg, _FILEINFO_);
00719     }
00720 
00721     // number/bandwidth matches for filters
00722     vector< pair<int, QString> > filters;
00723     filters.push_back(pair<int, QString>(1, "321"));
00724     filters.push_back(pair<int, QString>(2, "360"));
00725     filters.push_back(pair<int, QString>(3, "415"));
00726     filters.push_back(pair<int, QString>(4, "566"));
00727     filters.push_back(pair<int, QString>(5, "604"));
00728     filters.push_back(pair<int, QString>(6, "643"));
00729     filters.push_back(pair<int, QString>(7, "689"));
00730 
00731     for(int i = 0; i < pdsLab["FILTER_NUMBER"].Size(); i++) {
00732       bool found = false;
00733       bool match = false;
00734       for(int j = 0; !found && j < (int) filters.size(); j++) {
00735         if(toInt(pdsLab["FILTER_NUMBER"][i]) == filters[j].first) {
00736           found = true;
00737 
00738           match = (pdsLab["CENTER_FILTER_WAVELENGTH"][i] == filters[j].second);
00739         }
00740       }
00741 
00742       if(found && !match) {
00743         QString msg = "The [FILTER_NUMBER] and [CENTER_FILTER_WAVELENGTH] keywords do not correspond properly";
00744         throw IException(IException::Unknown, msg, _FILEINFO_);
00745       }
00746 
00747       if(!found) {
00748         QString msg = "The value of the keyword [FILTER_NUMBER] is invalid";
00749         throw IException(IException::Unknown, msg, _FILEINFO_);
00750       }
00751     }
00752 
00753     // Now make sure keywords that shouldn't exist dont
00754     QString invalidKeywords[] = {
00755       "SPACECRAFT_CLOCK_CNT_PARTITION"
00756     };
00757 
00758     for(unsigned int i = 0; i < sizeof(QString) / sizeof(invalidKeywords); i++) {
00759       if(pdsLab.HasKeyword(invalidKeywords[i])) {
00760         QString msg = "Keyword [";
00761         msg += invalidKeywords[i];
00762         msg += "] must not exist";
00763         throw IException(IException::Unknown, msg, _FILEINFO_);
00764       }
00765     }
00766 
00767     // Now check for keywords that must be integers
00768     PvlKeyword &orbitNumber = pdsLab["ORBIT_NUMBER"];
00769     QRegExp integerRegex("[0-9]+");
00770 
00771     if(orbitNumber.Size() != 1 || !integerRegex.exactMatch(orbitNumber[0])) {
00772       QString msg = "The value of keyword [ORBIT_NUMBER] is not valid";
00773       throw IException(IException::Unknown, msg, _FILEINFO_);
00774     }
00775 
00776     // Check for keywords that must be doubles or integers
00777     QRegExp numberRegex("[-+]{0,1}([0-9]*\\.[0-9]+)|([0-9]+\\.[0-9]*)|([0-9]+)");
00778     QString numericKeywords[] = {
00779       "LRO:BEGIN_TEMPERATURE_SCS",
00780       "LRO:MIDDLE_TEMPERATURE_SCS",
00781       "LRO:END_TEMPERATURE_SCS",
00782       "LRO:BEGIN_TEMPERATURE_FPA",
00783       "LRO:MIDDLE_TEMPERATURE_FPA",
00784       "LRO:END_TEMPERATURE_FPA",
00785       "INTERFRAME_DELAY",
00786       "EXPOSURE_DURATION"
00787     };
00788 
00789     for(unsigned int i = 0; i < sizeof(numericKeywords) / sizeof(QString); i++) {
00790       if(pdsLab[numericKeywords[i]].Size() != 1 || !numberRegex.exactMatch(pdsLab[numericKeywords[i]][0])) {
00791         QString msg = "The value of keyword [";
00792         msg += numericKeywords[i];
00793         msg += "] is not valid";
00794         throw IException(IException::Unknown, msg, _FILEINFO_);
00795       }
00796     }
00797 
00798     // Now check for keywords that must be dateTtime
00799     QRegExp timeRegex("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]*");
00800     QString timeKeywords[] = {
00801       "START_TIME",
00802       "STOP_TIME"
00803     };
00804 
00805     for(unsigned int i = 0; i < sizeof(timeKeywords) / sizeof(QString); i++) {
00806       if(pdsLab[timeKeywords[i]].Size() != 1 || !timeRegex.exactMatch(pdsLab[timeKeywords[i]][0])) {
00807         QString msg = "The value of keyword [";
00808         msg += timeKeywords[i];
00809         msg += "] is not valid";
00810         throw IException(IException::Unknown, msg, _FILEINFO_);
00811       }
00812     }
00813 
00814     // Now check keywords that must be clock counts
00815     QRegExp clockRegex("[0-9]+/[0-9]+:[0-9]+\\.{0,1}[0-9]*");
00816     QString clockKeywords[] = {
00817       "SPACECRAFT_CLOCK_START_COUNT",
00818       "SPACECRAFT_CLOCK_STOP_COUNT"
00819     };
00820 
00821     for(unsigned int i = 0; i < sizeof(clockKeywords) / sizeof(QString); i++) {
00822       if(pdsLab[clockKeywords[i]].Size() != 1 || !clockRegex.exactMatch(pdsLab[clockKeywords[i]][0])) {
00823         QString msg = "The value of keyword [";
00824         msg += clockKeywords[i];
00825         msg += "] is not valid";
00826         throw IException(IException::Unknown, msg, _FILEINFO_);
00827       }
00828     }
00829   }
00830   catch(IException &e) {
00831     QString msg = "The input product is out of date and has invalid labels. Please get an up to date version from the ASU LROC Team";
00832     throw IException(e, IException::Unknown, msg, _FILEINFO_);
00833   }
00834 }