// Main program void IsisMain(){ // Create an object for exporting Isis data ProcessExport p; // Open the input cube Cube *icube = p.SetInputCube("FROM"); // Conform to the Big-Endian format for FITS if(IsLsb()) p.SetOutputEndian(Isis::Msb); // Generate the name of the fits file and open it UserInterface &ui = Application::GetUserInterface(); // specify the bits per pixel string bitpix; if (ui.GetString ("BITTYPE") == "8BIT") bitpix = "8"; else if (ui.GetString ("BITTYPE") == "16BIT") bitpix = "16"; else if (ui.GetString ("BITTYPE") == "32BIT") bitpix = "-32"; else { string msg = "Pixel type of [" + ui.GetString("BITTYPE") + "] is unsupported"; throw iException::Message(iException::User, msg, _FILEINFO_); } // Determine bit size and calculate number of bytes to write // for each line. if (bitpix == "8") p.SetOutputType(Isis::UnsignedByte); if (bitpix == "16") p.SetOutputType(Isis::SignedWord); if (bitpix == "-32") p.SetOutputType(Isis::Real); // determine core base and multiplier, set up the stretch PvlGroup pix = icube->Label()->FindObject("IsisCube").FindObject("Core").FindGroup("Pixels"); double scale = pix["Multiplier"][0].ToDouble(); double base = pix["Base"][0].ToDouble(); if (ui.GetString("STRETCH") != "NONE" && bitpix != "-32") { if (ui.GetString("STRETCH") == "LINEAR") { p.SetInputRange(); } else if (ui.GetString("STRETCH") == "MANUAL") { p.SetInputRange(ui.GetDouble("MINIMUM"), ui.GetDouble("MAXIMUM")); } // create a proper scale so pixels look like 32bit data. scale = ((p.GetInputMaximum() - p.GetInputMinimum()) * (p.GetOutputMaximum() - p.GetOutputMinimum())); // round off after 14 decimals to avoid system architecture differences scale = ((floor(scale * 1e14)) / 1e14); // create a proper zero point so pixels look like 32bit data. base = -1.0 * (scale * p.GetOutputMinimum()) + p.GetInputMinimum(); // round off after 14 decimals to avoid system architecture differences base = ((floor(base * 1e14)) / 1e14); } ////////////////////////////////////////// // Write the minimal fits header // ////////////////////////////////////////// string header; // specify that this file conforms to simple fits standard header += FitsKeyword("SIMPLE", true, "T"); // specify the bits per pixel header += FitsKeyword("BITPIX", true, bitpix); // specify the number of data axes (2: samples by lines) int axes = 2; if (icube->Bands() > 1) { axes = 3; } header += FitsKeyword("NAXIS", true, iString(axes)); // specify the limit on data axis 1 (number of samples) header += FitsKeyword("NAXIS1", true, iString(icube->Samples())); // specify the limit on data axis 2 (number of lines) header += FitsKeyword("NAXIS2", true, iString(icube->Lines())); if (axes == 3){ header += FitsKeyword("NAXIS3", true, iString(icube->Bands())); } header += FitsKeyword("BZERO", true, base); header += FitsKeyword("BSCALE", true, scale); // Sky and All cases if (ui.GetString("INFO") == "SKY" || ui.GetString("INFO") == "ALL") { iString msg = "cube has not been skymapped"; PvlGroup map; if (icube->HasGroup("mapping")) { map = icube->GetGroup("mapping"); msg = (string)map["targetname"]; } // If we have sky we want it if (msg == "Sky") { double midRa = 0, midDec = 0; midRa = ((double)map["MaximumLongitude"] + (double)map["MinimumLongitude"])/2; midDec = ((double)map["MaximumLatitude"] + (double)map["MinimumLatitude"])/2; header += FitsKeyword("OBJCTRA", true, iString(midRa)); // Specify the Declination header += FitsKeyword("OBJCTDEC", true, iString(midDec)); } if (ui.GetString("INFO") == "ALL") { header += WritePvl("INSTRUME","Instrument","InstrumentId", icube, true); header += WritePvl("OBSERVER","Instrument","SpacecraftName", icube, true); header += WritePvl("OBJECT ","Instrument","TargetName", icube, true); // StartTime is sometimes middle of the exposure and somtimes beginning, // so StopTime can't be calculated off of exposure reliably. header += WritePvl("DATE-OBS","Instrument","StartTime", icube, true); // Some cameras don't have StopTime if (icube->HasGroup("Instrument")) { PvlGroup inst = icube->GetGroup("Instrument"); if (inst.HasKeyword("StopTime")) { header += WritePvl("TIME_END","Instrument","StopTime", icube, true); } if (inst.HasKeyword("ExposureDuration")) { header += WritePvl("EXPTIME","Instrument","ExposureDuration", icube, false); } } } // If we were set on SKY and Sky doesn't exist else if (msg != "Sky") { throw iException::Message(iException::User,msg,_FILEINFO_); } } // signal the end of the header header += FitsKeyword("END", false, ""); // fill the rest of the fits header with space so to conform with the fits header // size of 2880 bytes for (int i = header.length() % 2880 ; i < 2880 ; i++) header += " "; // open the cube for writing string to = ui.GetFilename("TO","fits"); ofstream fout; fout.open (to.c_str (), ios::out|ios::binary); if (!fout.is_open ()) { string msg = "Cannot open fits output file"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } fout.seekp(0); fout.write(header.c_str(),header.length()); // write the raw cube data p.StartProcess (fout); // Finish off data area to a number n % 2880 == 0 is true // 2880 is the size of the data blocks int count = 2880 - (fout.tellp() % 2880); for (int i = 0; i < count; i++) { // Write nul characters as needed. ascii 0, hex 00... fout.write("\0", 1); } fout.close(); p.EndProcess(); }
void IsisMain () { Pvl pdsLab; FileList list; UserInterface &ui = Application::GetUserInterface(); list.read(ui.GetFileName("FROMLIST")); if (list.size() < 1) { QString msg = "The list file [" + ui.GetFileName("FROMLIST") + "does not contain any data"; throw IException(IException::User, msg, _FILEINFO_); } g_productVersionId = ui.GetString("VERSIONIDSTRING"); for (int i = 0; i < list.size(); i++) { Pvl tempPvl; tempPvl.read(list[i].toString()); OriginalLabel origLab(list[i].toString()); pdsLab = origLab.ReturnLabels(); QString prodId = pdsLab["PRODUCT_ID"][0]; if (productId == "") productId = prodId; if (productId != prodId) { QString msg = "This program is intended for use on a single LROC WAC images only."; msg += "The ProductIds do not match."; throw IException(IException::User, msg, _FILEINFO_); } Isis::PvlGroup &inst = tempPvl.findGroup("Instrument", Pvl::Traverse); QString instId = (QString) inst["InstrumentId"]; QString framelets = (QString) inst["Framelets"]; QString numFrames = inst["NumFramelets"]; if (instId != "WAC-VIS" && instId != "WAC-UV") { QString msg = "This program is intended for use on LROC WAC images only. ["; msg += list[i].toString() + "] does not appear to be a WAC image."; throw IException(IException::User, msg, _FILEINFO_); } QString instModeId = (QString) inst["InstrumentModeId"]; if (instrumentModeId == "") instrumentModeId = instModeId; if (numFramelets == 0) numFramelets = toInt(numFrames); g_isIoF = tempPvl.findGroup("Radiometry", Pvl::Traverse).findKeyword("RadiometricType")[0].toUpper() == "IOF"; if (instId == "WAC-VIS" && framelets == "Even") { viseven = new Cube(); viseven->open(list[i].toString()); } else if (instId == "WAC-VIS" && framelets == "Odd") { visodd = new Cube(); visodd->open(list[i].toString()); } if (instId == "WAC-UV" && framelets == "Even") { uveven = new Cube(); uveven->open(list[i].toString()); } else if (instId == "WAC-UV" && framelets == "Odd") { uvodd = new Cube(); uvodd->open(list[i].toString()); } } // Determine our band information based on // INSTRUMENT_MODE_ID - FILTER_NUMBER is // only going to be used for BW images if (instrumentModeId == "COLOR") { numUVFilters = 2; numVisFilters = 5; numSamples = COLOR_SAMPLES; } else if (instrumentModeId == "VIS") { numUVFilters = 0; numVisFilters = 5; numSamples = VIS_SAMPLES; } else if (instrumentModeId == "UV") { numUVFilters = 2; numVisFilters = 0; numSamples = UV_SAMPLES; } else if (instrumentModeId == "BW") { numUVFilters = 0; numVisFilters = 1; numSamples = BW_SAMPLES; } numLines = numFramelets * (UV_LINES * numUVFilters + VIS_LINES * numVisFilters); out = new Cube(); out->setDimensions(numSamples, numLines, 1); out->setPixelType(Isis::Real); FileName mergedCube = FileName::createTempFile( "$TEMPORARY/" + FileName(ui.GetFileName("TO")).baseName() + ".cub"); out->create(mergedCube.expanded()); mergeFramelets(); /* FileName outFile(ui.GetFileName("TO", "img")); QString outFileName(outFile.expanded()); ofstream oCube(outFileName.c_str()); p.OutputLabel(oCube); p.StartProcess(oCube); oCube.close(); p.EndProcess(); */ out->close(); delete out; out = NULL; if (uveven) { uveven->close(); delete uveven; uveven = NULL; } if (uvodd) { uvodd->close(); delete uvodd; uvodd = NULL; } if (viseven) { viseven->close(); delete viseven; viseven = NULL; } if (visodd) { visodd->close(); delete visodd; visodd = NULL; } // Export data ProcessExport pe; // Setup the input cube Cube *inCube = pe.SetInputCube(mergedCube.expanded(), CubeAttributeInput()); pe.SetOutputType(Isis::Real); pe.SetOutputEndian(Isis::Lsb); pe.SetOutputRange(Isis::VALID_MIN4, Isis::VALID_MAX4); pe.SetOutputNull(Isis::NULL4); pe.SetOutputLrs(Isis::LOW_REPR_SAT4); pe.SetOutputLis(Isis::LOW_INSTR_SAT4); pe.SetOutputHis(Isis::HIGH_INSTR_SAT4); pe.SetOutputHrs(Isis::HIGH_REPR_SAT4); FileName tempFile = FileName::createTempFile( "$TEMPORARY/" + FileName(ui.GetFileName("TO")).baseName() + ".temp"); QString tempFileName(tempFile.expanded()); ofstream temporaryFile(tempFileName.toAscii().data()); pe.StartProcess(temporaryFile); temporaryFile.close(); // Calculate MD5 Checksum g_md5Checksum = MD5Checksum(tempFileName); FileName outFile(ui.GetFileName("TO")); QString outFileName(outFile.expanded()); ifstream inFile(tempFileName.toAscii().data()); ofstream pdsFile(outFileName.toAscii().data()); // Output the label OutputLabel(pdsFile, inCube, pdsLab); // Then copy the image data CopyData(inFile, pdsFile); pdsFile.close(); pe.EndProcess(); remove((mergedCube.expanded()).toAscii().data()); remove(tempFileName.toAscii().data()); return; }