USGS

Isis 3.0 Application Source Code Reference

Home

lrowac2pds.cpp

Go to the documentation of this file.
00001 #include "Isis.h"
00002 #include <cstdio>
00003 #include <QString>
00004 #include <QRegExp>
00005 #include "FileList.h"
00006 #include "Brick.h"
00007 #include "OriginalLabel.h"
00008 #include "Brick.h"
00009 #include "History.h"
00010 #include "Stretch.h"
00011 #include "iTime.h"
00012 #include "ProcessExport.h"
00013 #include "PvlTranslationManager.h"
00014 #include "PvlFormatPds.h"
00015 #include "md5.h"
00016 #include "md5wrapper.h"
00017 #include "OriginalLabel.h"
00018 #include <sstream>
00019 
00020 #define COLOR_SAMPLES 704
00021 #define VIS_SAMPLES 704
00022 #define UV_SAMPLES 128
00023 #define BW_SAMPLES 1024
00024 #define VIS_LINES 14
00025 #define UV_LINES 4
00026 
00027 using namespace std;
00028 using namespace Isis;
00029 
00030 vector<int> frameletLines;
00031 
00032 void ResetGlobals ();
00033 void mergeFramelets ();
00034 QString MD5Checksum ( QString filename );
00035 void OutputLabel ( std::ofstream &fout, Cube* cube, Pvl &pdsLab );
00036 void CopyData ( std::ifstream &fin, std::ofstream &fout );
00037 
00038 std::vector<int> padding;
00039 int colorOffset = 0;
00040 int inputCubeLines = 0;
00041 
00042 // Output UV Files
00043 Cube *uveven = NULL;
00044 Cube *uvodd = NULL;
00045 
00046 // Output VIS Files
00047 Cube *viseven = NULL;
00048 Cube *visodd = NULL;
00049 
00050 Cube* out = NULL;
00051 
00052 QString instrumentModeId = "";
00053 QString productId = "";
00054 QString g_productVersionId = "N/A";
00055 
00056 QString g_md5Checksum;
00057 
00058 int numFramelets = 0;
00059 int numSamples = 0;
00060 int numLines = 0;
00061 int numUVFilters = 0;
00062 int numVisFilters = 0;
00063 
00064 bool g_isIoF;
00065 
00066 void IsisMain () {
00067     Pvl pdsLab;
00068 
00069     FileList list;
00070     UserInterface &ui = Application::GetUserInterface();
00071     list.read(ui.GetFileName("FROMLIST"));
00072 
00073     if (list.size() < 1) {
00074         QString msg = "The list file [" + ui.GetFileName("FROMLIST") + "does not contain any data";
00075         throw IException(IException::User, msg, _FILEINFO_);
00076     }
00077 
00078     g_productVersionId = ui.GetString("VERSIONIDSTRING");
00079 
00080     for (int i = 0; i < list.size(); i++) {
00081 
00082         Pvl tempPvl;
00083         tempPvl.Read(list[i].toString());
00084 
00085         OriginalLabel origLab(list[i].toString());
00086         pdsLab = origLab.ReturnLabels();
00087 
00088         QString prodId = pdsLab["PRODUCT_ID"][0];
00089         if (productId == "")
00090             productId = prodId;
00091 
00092         if (productId != prodId) {
00093             QString msg = "This program is intended for use on a single LROC WAC images only.";
00094             msg += "The ProductIds do not match.";
00095             throw IException(IException::User, msg, _FILEINFO_);
00096         }
00097 
00098         Isis::PvlGroup &inst = tempPvl.FindGroup("Instrument", Pvl::Traverse);
00099         QString instId = (QString) inst["InstrumentId"];
00100         QString framelets = (QString) inst["Framelets"];
00101         QString numFrames = inst["NumFramelets"];
00102 
00103         if (instId != "WAC-VIS" && instId != "WAC-UV") {
00104             QString msg = "This program is intended for use on LROC WAC images only. [";
00105             msg += list[i].toString() + "] does not appear to be a WAC image.";
00106             throw IException(IException::User, msg, _FILEINFO_);
00107         }
00108 
00109         QString instModeId = (QString) inst["InstrumentModeId"];
00110         if (instrumentModeId == "")
00111             instrumentModeId = instModeId;
00112         if (numFramelets == 0)
00113             numFramelets = toInt(numFrames);
00114         g_isIoF = tempPvl.FindGroup("Radiometry", Pvl::Traverse).FindKeyword("RadiometricType")[0].toUpper() == "IOF";
00115 
00116         if (instId == "WAC-VIS" && framelets == "Even") {
00117             viseven = new Cube();
00118             viseven->open(list[i].toString());
00119         }
00120         else if (instId == "WAC-VIS" && framelets == "Odd") {
00121             visodd = new Cube();
00122             visodd->open(list[i].toString());
00123         }
00124         if (instId == "WAC-UV" && framelets == "Even") {
00125             uveven = new Cube();
00126             uveven->open(list[i].toString());
00127         }
00128         else if (instId == "WAC-UV" && framelets == "Odd") {
00129             uvodd = new Cube();
00130             uvodd->open(list[i].toString());
00131         }
00132     }
00133 
00134     // Determine our band information based on
00135     // INSTRUMENT_MODE_ID - FILTER_NUMBER is
00136     // only going to be used for BW images
00137     if (instrumentModeId == "COLOR") {
00138         numUVFilters = 2;
00139         numVisFilters = 5;
00140 
00141         numSamples = COLOR_SAMPLES;
00142     }
00143     else if (instrumentModeId == "VIS") {
00144         numUVFilters = 0;
00145         numVisFilters = 5;
00146 
00147         numSamples = VIS_SAMPLES;
00148     }
00149     else if (instrumentModeId == "UV") {
00150         numUVFilters = 2;
00151         numVisFilters = 0;
00152 
00153         numSamples = UV_SAMPLES;
00154     }
00155     else if (instrumentModeId == "BW") {
00156         numUVFilters = 0;
00157         numVisFilters = 1;
00158 
00159         numSamples = BW_SAMPLES;
00160     }
00161 
00162     numLines = numFramelets * (UV_LINES * numUVFilters + VIS_LINES * numVisFilters);
00163 
00164     out = new Cube();
00165     out->setDimensions(numSamples, numLines, 1);
00166     out->setPixelType(Isis::Real);
00167 
00168     FileName mergedCube = FileName::createTempFile(
00169         "$TEMPORARY/" + FileName(ui.GetFileName("TO")).baseName() + ".cub");
00170     out->create(mergedCube.expanded());
00171 
00172     mergeFramelets();
00173 
00174     /*
00175 
00176      FileName outFile(ui.GetFileName("TO", "img"));
00177      QString outFileName(outFile.expanded());
00178      ofstream oCube(outFileName.c_str());
00179      p.OutputLabel(oCube);
00180      p.StartProcess(oCube);
00181      oCube.close();
00182      p.EndProcess();
00183 
00184      */
00185 
00186     out->close();
00187     delete out;
00188     out = NULL;
00189 
00190     if (uveven) {
00191         uveven->close();
00192         delete uveven;
00193         uveven = NULL;
00194     }
00195 
00196     if (uvodd) {
00197         uvodd->close();
00198         delete uvodd;
00199         uvodd = NULL;
00200     }
00201 
00202     if (viseven) {
00203         viseven->close();
00204         delete viseven;
00205         viseven = NULL;
00206     }
00207 
00208     if (visodd) {
00209         visodd->close();
00210         delete visodd;
00211         visodd = NULL;
00212     }
00213 
00214     // Export data
00215 
00216     ProcessExport pe;
00217 
00218     // Setup the input cube
00219     Cube *inCube = pe.SetInputCube(mergedCube.expanded(), CubeAttributeInput());
00220 
00221     pe.SetOutputType(Isis::Real);
00222     pe.SetOutputEndian(Isis::Lsb);
00223 
00224     pe.SetOutputRange(Isis::VALID_MIN4, Isis::VALID_MAX4);
00225 
00226     pe.SetOutputNull(Isis::NULL4);
00227     pe.SetOutputLrs(Isis::LOW_REPR_SAT4);
00228     pe.SetOutputLis(Isis::LOW_INSTR_SAT4);
00229     pe.SetOutputHis(Isis::HIGH_INSTR_SAT4);
00230     pe.SetOutputHrs(Isis::HIGH_REPR_SAT4);
00231 
00232     FileName tempFile = FileName::createTempFile(
00233         "$TEMPORARY/" + FileName(ui.GetFileName("TO")).baseName() + ".temp");
00234     QString tempFileName(tempFile.expanded());
00235     ofstream temporaryFile(tempFileName.toAscii().data());
00236 
00237     pe.StartProcess(temporaryFile);
00238     temporaryFile.close();
00239 
00240     // Calculate MD5 Checksum
00241     g_md5Checksum = MD5Checksum(tempFileName);
00242 
00243     FileName outFile(ui.GetFileName("TO"));
00244     QString outFileName(outFile.expanded());
00245     ifstream inFile(tempFileName.toAscii().data());
00246     ofstream pdsFile(outFileName.toAscii().data());
00247 
00248     // Output the label
00249     OutputLabel(pdsFile, inCube, pdsLab);
00250 
00251     // Then copy the image data
00252     CopyData(inFile, pdsFile);
00253 
00254     pdsFile.close();
00255 
00256     pe.EndProcess();
00257 
00258     remove((mergedCube.expanded()).toAscii().data());
00259     remove(tempFileName.toAscii().data());
00260     return;
00261 }
00262 
00263 void ResetGlobals () {
00264     colorOffset = 0;
00265     frameletLines.clear();
00266 
00267     uveven = NULL;
00268     uvodd = NULL;
00269     viseven = NULL;
00270     visodd = NULL;
00271 
00272     out = NULL;
00273 
00274     instrumentModeId = "";
00275     productId = "";
00276     g_md5Checksum = "";
00277 
00278     numFramelets = 0;
00279     numSamples = 0;
00280     numLines = 0;
00281     numUVFilters = 0;
00282     numVisFilters = 0;
00283 
00284     g_isIoF = false;
00285 }
00286 
00287 //! Merges each of the individual WAC framelets into the right place
00288 void mergeFramelets () {
00289     Brick *uvevenManager = NULL, *uvoddManager = NULL, *visevenManager = NULL, *visoddManager = NULL;
00290 
00291     if (numUVFilters > 0) {
00292         uvevenManager = new Brick(*uveven, UV_SAMPLES, UV_LINES, numUVFilters);
00293         uvoddManager = new Brick(*uvodd, UV_SAMPLES, UV_LINES, numUVFilters);
00294 
00295         uvevenManager->begin();
00296         uvoddManager->begin();
00297     }
00298     if (numVisFilters > 0) {
00299         visevenManager = new Brick(*viseven, numSamples, VIS_LINES, numVisFilters);
00300         visoddManager = new Brick(*visodd, numSamples, VIS_LINES, numVisFilters);
00301 
00302         visevenManager->begin();
00303         visoddManager->begin();
00304     }
00305 
00306     Brick outManager(*out, numSamples, UV_LINES * numUVFilters + VIS_LINES * numVisFilters, 1);
00307     outManager.begin();
00308 
00309     // For each frame
00310     for (int f = 0; f < numFramelets; f++) {
00311         // write out the UV first
00312         if (numUVFilters > 0) {
00313             uveven->read(*uvevenManager);
00314             uvodd->read(*uvoddManager);
00315 
00316             int pad = (numSamples - UV_SAMPLES) / 2;
00317             for (int line = 0; line < numUVFilters * UV_LINES; line++) {
00318                 int offset = numSamples * line;
00319                 // left padding
00320                 for (int i = 0; i < pad; i++)
00321                     outManager[offset + i] = Isis::Null;
00322                 for (int i = 0; i < UV_SAMPLES; i++) {
00323                     int index = line * UV_SAMPLES + i;
00324                     if (f % 2 == 0)
00325                         outManager[i + offset + pad] = uvoddManager->at(index);
00326                     else
00327                         outManager[i + offset + pad] = uvevenManager->at(index);
00328                 }
00329                 // right padding
00330                 for (int i = 0; i < pad; i++)
00331                     outManager[i + offset + pad + UV_SAMPLES] = Isis::Null;
00332             }
00333             uvevenManager->next();
00334             uvoddManager->next();
00335         }
00336         // then the vis
00337         if (numVisFilters > 0) {
00338             viseven->read(*visevenManager);
00339             visodd->read(*visoddManager);
00340 
00341             int offset = numUVFilters * UV_LINES * numSamples;
00342             for (int i = 0; i < numVisFilters * VIS_LINES * numSamples; i++) {
00343                 if (f % 2 == 0)
00344                     outManager[i + offset] = visoddManager->at(i);
00345                 else
00346                     outManager[i + offset] = visevenManager->at(i);
00347             }
00348 
00349             visevenManager->next();
00350             visoddManager->next();
00351         }
00352 
00353         out->write(outManager);
00354         outManager.next();
00355     }
00356 }
00357 
00358 QString MD5Checksum ( QString filename ) {
00359     md5wrapper md5;
00360     QString checkSum = md5.getHashFromFile(filename);
00361     return checkSum;
00362 }
00363 
00364 void OutputLabel ( std::ofstream &fout, Cube* cube, Pvl &labelPvl ) {
00365     //Pvl to store the labels
00366     Pvl outLabel;
00367     PvlFormatPds *p_formatter = new PvlFormatPds("$lro/translations/pdsExportRootGen.typ");
00368     labelPvl.SetFormat(p_formatter);
00369     labelPvl.SetTerminator("END");
00370     //Set up the directory where the translations are
00371     PvlGroup dataDir(Preference::Preferences().FindGroup("DataDirectory"));
00372     QString transDir = (QString) dataDir["Lro"] + "/translations/";
00373 
00374     stringstream stream;
00375     QString pdsLabel = "";
00376 
00377     //Translate the Original Pds Label
00378     FileName transFile(transDir + "lrowacPdsLabelExport.trn");
00379     PvlTranslationManager labelXlator(labelPvl, transFile.expanded());
00380     labelXlator.Auto(outLabel);
00381 
00382     // Copy any Translation changes over
00383     for (int i = 0; i < outLabel.Keywords(); i++) {
00384         bool hasUnit = false;
00385         QString unit = "";
00386         if (labelPvl[outLabel[i].Name()].Unit() != "") {
00387             hasUnit = true;
00388             unit = labelPvl[outLabel[i].Name()].Unit();
00389         }
00390         bool hasComment = false;
00391         QString comment = "";
00392         if (labelPvl[outLabel[i].Name()].Comments() > 0) {
00393             hasComment = true;
00394             comment = labelPvl[outLabel[i].Name()].Comment(0);
00395         }
00396         labelPvl[outLabel[i].Name()] = outLabel[i];
00397 
00398         if (hasUnit)
00399             labelPvl[outLabel[i].Name()].SetUnits(unit);
00400         if (hasComment)
00401             labelPvl[outLabel[i].Name()].AddComment(comment);
00402     }
00403 
00404     //Update the product ID
00405     QString prod_id = labelPvl["PRODUCT_ID"][0];
00406     labelPvl["PRODUCT_ID"][0].replace((prod_id.length()-1), 1, "C");
00407 
00408     // Update the product creation time
00409     labelPvl["PRODUCT_CREATION_TIME"].SetValue(iTime::CurrentGMT());
00410 
00411     labelPvl["PRODUCT_VERSION_ID"].SetValue(g_productVersionId);
00412 
00413     // Update the "IMAGE" Object
00414     PvlObject &imageObject = labelPvl.FindObject("IMAGE");
00415     imageObject.Clear();
00416     imageObject += PvlKeyword("LINES", toString(cube->lineCount()));
00417     imageObject += PvlKeyword("LINE_SAMPLES", toString(cube->sampleCount()));
00418     imageObject += PvlKeyword("SAMPLE_BITS", toString(32));
00419     imageObject += PvlKeyword("SAMPLE_TYPE", "PC_REAL");
00420     imageObject += PvlKeyword("VALID_MINIMUM", "16#FF7FFFFA#");
00421     imageObject += PvlKeyword("NULL", "16#FF7FFFFB#");
00422     imageObject += PvlKeyword("LOW_REPR_SATURATION", "16#FF7FFFFC#");
00423     imageObject += PvlKeyword("LOW_INSTR_SATURATION", "16#FF7FFFFD#");
00424     imageObject += PvlKeyword("HIGH_INSTR_SATURATION", "16#FF7FFFFE#");
00425     imageObject += PvlKeyword("HIGH_REPR_SATURATION", "16#FF7FFFFF#");
00426     if (g_isIoF == true)
00427         imageObject += PvlKeyword("UNIT", "\"I/F\"");
00428     else
00429     imageObject += PvlKeyword("UNIT", "W / (m**2 micrometer sr)");
00430     imageObject += PvlKeyword("MD5_CHECKSUM", g_md5Checksum);
00431 
00432     stream << labelPvl;
00433 
00434     int recordBytes = cube->sampleCount();
00435     int labelRecords = (int) ((stream.str().length()) / recordBytes) + 1;
00436 
00437     labelPvl["RECORD_BYTES"] = toString(recordBytes);
00438     labelPvl["FILE_RECORDS"] = toString((int) (cube->lineCount() * 4 + labelRecords));
00439     labelPvl["LABEL_RECORDS"] = toString(labelRecords);
00440     labelPvl["^IMAGE"] = toString((int) (labelRecords + 1));
00441 
00442     stream.str(std::string());
00443 
00444     stream << labelPvl;
00445     pdsLabel += stream.str().c_str();
00446 
00447     while ((int)pdsLabel.length() < (int) (labelRecords * recordBytes)) {
00448         pdsLabel += '\n';
00449     }
00450 
00451     fout << pdsLabel;
00452     return;
00453 }
00454 
00455 void CopyData ( std::ifstream &fin, std::ofstream &fout ) {
00456     char line[704];
00457     while (!fin.eof()) {
00458         fin.read(line, 704);
00459         fout.write(line, fin.gcount());
00460     }
00461 }
00462