|
Isis 3.0 Application Source Code Reference |
Home |
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