Example #1
0
// 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();
}
Example #2
0
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;
}