コード例 #1
0
TagBox::TagBox(ToolPanel *panel, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, wxString boxname, wxString modpath)
	: wxComboBox(panel, id, label, wxDefaultPosition, size)
{
	wxString filename, filepath;
	wxString readline, tag, text;
	TextFile opfile;
	bool check;

	path = modpath;
	name = boxname;
	diagbox = NULL;
	labelset = false;
	tag = "";

	if(panel->mainwin) diagbox = panel->mainwin->diagbox;

	diagbox->Write("\nTagBox init " + name + "\n");

	// tag history load
	if(name == "") {
		diagbox->Write("Tag file not set\n");
		return;
	}
	filename =  name + "tags.ini";
	check = opfile.Open(path + "/Tags/" + filename);
	if(!check) {
		if(diagbox) diagbox->Write("No tag history\n");
		return;
	}

	diagbox->Write("Reading tag history " + filename + "\n");

	readline = opfile.ReadLine();

	while(!readline.IsEmpty()) {
		//diagbox->Write("Readline " + readline + "\n");
		readline = readline.AfterFirst(' ');
		readline.Trim();
		tag = readline;
		Insert(tag, 0);
		//diagbox->Write("Insert " + tag + "\n");
		readline = opfile.ReadLine();
	}

	opfile.Close();	
	SetLabel(tag);
	diagbox->Write(name + " " + tag + "\n");
	if(tag != "") labelset = true;
}
コード例 #2
0
ファイル: hypobase.cpp プロジェクト: HypoModel/HypoModBase
void MainFrame::MainLoad()
{
	long numdat;
	int i, check, boxindex;

	wxString filename, filepath;
	wxString readline, numstring;

	TextFile infile;
	wxPoint pos;
    wxSize size;

	//filepath = GetPath();
	filepath = "Init//";

	// Box Load
	filename = "mainbox.ini";

	check = infile.Open(filepath + filename);
	if(!check) return;
	readline = infile.ReadLine();
	//tofp.WriteLine(readline);
	while(!readline.IsEmpty()) {
		numstring = readline.BeforeFirst(' ');
		numstring.ToLong(&numdat);
		boxindex = numdat;
		if(boxindex >= toolset->numtools) break;

		pos.x = ReadNextData(&readline);
		pos.y = ReadNextData(&readline);
		size.x = ReadNextData(&readline);
		size.y = ReadNextData(&readline);
		if(toolset->box[boxindex]->servant) toolset->box[boxindex]->visible = (bool)ReadNextData(&readline);
		else toolset->box[boxindex]->visible = true;

		if(pos.x >= -5000 && pos.x < 5000 && pos.y >= -5000 && pos.y < 5000) toolset->box[boxindex]->mpos = pos;
		if(size.x >= 50 && size.x < 2000 && size.y >= 50 && size.y < 2000) toolset->box[boxindex]->boxsize = size;

		readline = infile.ReadLine();          // Read next line
		//tofp.WriteLine(readline);
	}
	infile.Close();

	for(i=0; i<toolset->numtools; i++) {
		toolset->box[i]->ReSize();
		toolset->box[i]->Show(toolset->box[i]->visible);
	}
}
コード例 #3
0
ファイル: UserInterface.cpp プロジェクト: corburn/ISIS
  /**
   * Loads the user entered batchlist file into a private variable for later use
   *
   * @param file The batchlist file to load
   *
   *  @history 2010-03-26 Sharmila Prasad - Remove the restriction of the number of
   *           columns in the batchlist file to 10.
   * @throws Isis::IException::User - The batchlist does not contain any data
   */
  void UserInterface::LoadBatchList(const QString file) {
    // Read in the batch list
    TextFile temp;
    try {
      temp.Open(file);
    }
    catch (IException &e) {
      QString msg = "The batchlist file [" + file
                   + "] could not be opened";
      throw IException(IException::User, msg, _FILEINFO_);
    }

    p_batchList.resize(temp.LineCount());

    for(int i = 0; i < temp.LineCount(); i ++) {
      QString t;
      temp.GetLine(t);

      // Convert tabs to spaces but leave tabs inside quotes alone
      t = IString(t).Replace("\t", " ", true).ToQt();

      t = IString(t).Compress().ToQt().trimmed();
      // Allow " ," " , " or ", " as a valid single seperator
      t = IString(t).Replace(" ,", ",", true).ToQt();
      t = IString(t).Replace(", ", ",", true).ToQt();
      // Convert all spaces to "," the use "," as delimiter
      t = IString(t).Replace(" ", ",", true).ToQt();
      int j = 0;

      QStringList tokens = t.split(",");

      foreach(QString token, tokens) {
        // removes quotes from tokens. NOTE: also removes escaped quotes.
        token = token.remove(QRegExp("[\"']"));
        p_batchList[i].push_back(token);
        j ++ ;
      }

      p_batchList[i].resize(j);
      // Every row in the batchlist must have the same number of columns
      if(i == 0)
        continue;
      if(p_batchList[i - 1].size() != p_batchList[i].size()) {
        QString msg =
          "The number of columns must be constant in batchlist";
        throw IException(IException::User, msg, _FILEINFO_);
      }
    }
コード例 #4
0
void ToolBox::OnClose(wxCloseEvent& event)
{
	TextFile ofp;
	wxString text;
	ofp.Open("boxdiag.txt");

	if(servant || child) {
		Show(false);
		ofp.WriteLine(text.Format("hide box %d, child %d", boxindex, child));
	}
	else if(canclose) {
		ofp.WriteLine(text.Format("close box %d, mod boxes %d", boxindex, toolset->numtools));
		//if(mod != NULL) mod->modtools.RemoveBox(boxindex);
		//mainwin->toolset.RemoveBox(boxindex);
		toolset->RemoveBox(boxindex);
		Destroy();
	}

	ofp.Close();
}
コード例 #5
0
ファイル: hypodat.cpp プロジェクト: hypomod/HypoModelBase
void GraphBase::BaseLoad(wxString path, wxString tag, wxTextCtrl *textbox)
{
	int i, index;
	TextFile infile;
	wxString readline, filename, filetag;
	wxString text, numstring, namestring, basestring;
	wxString gtag, gname;
	double numdat;
	GraphDat *graph;
	int version;

	filename = "gbase-" + tag + ".dat";

	//if(!infile.Open(initpath + "/Graphs/" + filename)) return;
	if(!infile.Open(path + "/" + filename)) return;

	if(textbox) textbox->AppendText(text.Format("Loading %d graphs\n", numgraphs));

	i = 0;
	readline = infile.ReadLine();

	// Version check

	//fileversion = ParseLong(&vstring, 'v');
	//textbox->AppendText(text.Format("Base file version %d\n", fileversion));
	//if(fileversion < version) textbox->AppendText(text.Format("Create base index\n"));

	while(!readline.IsEmpty()) {

		if(readline.GetChar(0) == 'v') version = ParseLong(&readline, 'v');          // check file version for backwards compatability
		else version = 0;
		//textbox->AppendText(text.Format("Base file version %d\n", version));
		//textbox->AppendText(text.Format("Readline %s\n", readline));

		if(version >= 2) {                                                  // Modern, reference by tag
			gtag = ParseString(&readline, 'g');
			graph = GetGraph(gtag);
			if(graph) graph->LoadDat(readline, version);
		}
		else {
			//GetGraphFromName(gname)->LoadDat(readline, version);              // Should add code to chop off any tag first
			//int ndex = readline.Find("name");
			//textbox->AppendText(text.Format("Base file version %d\n", version));
			//textbox->AppendText(text.Format("Readline %s\n", readline));
			namestring = readline.Mid(readline.Find("name"));
			//textbox->AppendText(text.Format("Name string %s\n", namestring));
			gname = ParseString(&namestring, 'e');
			gname.Replace("_", " ");
			if(textbox) textbox->AppendText(text.Format("gname %s\n", gname));
			graph = GetGraphFromName(gname);
			if(graph) graph->LoadDat(readline, version);
		}
			
		//graphstore[i].LoadDat(readline, version);
			
		if(infile.End()) break;
		readline = infile.ReadLine();	
		i++;	
	}
	infile.Close();


	// Read graphbase entries

	/*
	while(!readline.IsEmpty()) {
		graphstore[i].diagbox = mainwin->diagbox;
		graphstore[i].LoadDat(readline, version);
			
		if(infile.End()) break;
		readline = infile.ReadLine();	
		i++;	
	}
	infile.Close();
	*/
}
コード例 #6
0
ファイル: hypomodel.cpp プロジェクト: hypomod/HypoModelBase
void HypoMain::OptionLoad()
{
    long numdat;
    int check;
    
    wxString filename;
    wxString readline, numstring, tag;
    
    filename = "Init/hypoprefs.ini";
    
    wxTextFile opfile(filename);
    
    if(!opfile.Exists()) {
        startmod = 13;
        numdraw = 3;
        ylabels = 5;
        diagnostic = 1;
        datsample = 1;
        basic = 0;
    }
    else {
        
        opfile.Open();
        
        readline = opfile.GetFirstLine();
        
        while(!readline.IsEmpty()) {
            tag = readline.BeforeFirst(' ');
            readline = readline.AfterFirst(' ');
            readline.Trim();
            readline.ToLong(&numdat);
            prefstore[tag] = numdat;
            //if(diagnostic) ofp.WriteLine(text.Format("Model Param ID %d, Value %.4f\n", id, datval));
            if(opfile.Eof()) return;
            readline = opfile.GetNextLine();
        }
        
        opfile.Close();
        
        startmod = prefstore["startmod"];
        numdraw = prefstore["numdraw"];
        viewheight = prefstore["viewheight"];
        viewwidth = prefstore["viewwidth"];
        ylabels = prefstore["ylabels"];
        datsample = prefstore["datsample"];
        basic = prefstore["basic"];
        diagnostic = prefstore["diagnostic"];
        
    }
    
    filename = "Init/hypopaths.ini";
    TextFile infile;
    check = infile.Open(filename);
    
    if(!check) {
        datapath = "Data";
        parampath = "Params";
        outpath = "";
        modpath = "";
        return;
    }
    
    readline = infile.ReadLine();
    datapath = readline.Trim();
    readline = infile.ReadLine();
    parampath = readline.Trim();
    readline = infile.ReadLine();
    outpath = readline.Trim();
    readline = infile.ReadLine();
    modpath = readline.Trim();
    
    opfile.Close();
}
コード例 #7
0
ファイル: nocam2map.cpp プロジェクト: assutech/isis3
void IsisMain() {
  //Create a process to create the input cubes
  Process p;
  //Create the input cubes, matching sample/lines
  Cube *inCube = p.SetInputCube ("FROM");
  Cube *latCube = p.SetInputCube("LATCUB", SpatialMatch);
  Cube *lonCube = p.SetInputCube("LONCUB", SpatialMatch);

  //A 1x1 brick to read in the latitude and longitude DN values from
  //the specified cubes
  Brick latBrick(1,1,1, latCube->PixelType());
  Brick lonBrick(1,1,1, lonCube->PixelType());

  UserInterface &ui = Application::GetUserInterface();

  //Set the sample and line increments
  int sinc = (int)(inCube->Samples() * 0.10);
  if(ui.WasEntered("SINC")) {
    sinc = ui.GetInteger("SINC");
  }

  int linc = (int)(inCube->Lines() * 0.10);
  if(ui.WasEntered("LINC")) {
    linc = ui.GetInteger("LINC");
  }

  //Set the degree of the polynomial to use in our functions
  int degree = ui.GetInteger("DEGREE");

  //We are using a polynomial with two variables
  PolynomialBivariate sampFunct(degree); 
  PolynomialBivariate lineFunct(degree);

  //We will be solving the function using the least squares method
  LeastSquares sampSol(sampFunct);
  LeastSquares lineSol(lineFunct);

  //Setup the variables for solving the stereographic projection
  //x = cos(latitude) * sin(longitude - lon_center)
  //y = cos(lat_center) * sin(latitude) - sin(lat_center) * cos(latitude) * cos(longitude - lon_center)

  //Get the center lat and long from the input cubes
  double lat_center = latCube->Statistics()->Average() * PI/180.0;
  double lon_center = lonCube->Statistics()->Average() * PI/180.0;


  /**
   * Loop through lines and samples projecting the latitude and longitude at those
   * points to stereographic x and y and adding these points to the LeastSquares 
   * matrix. 
   */
  for(int i = 1; i <= inCube->Lines(); i+= linc) {
    for(int j = 1; j <= inCube->Samples(); j+= sinc) {
      latBrick.SetBasePosition(j, i, 1);
      latCube->Read(latBrick);
      if(IsSpecial(latBrick.at(0))) continue;
      double lat = latBrick.at(0) * PI/180.0;
      lonBrick.SetBasePosition(j, i, 1);
      lonCube->Read(lonBrick);
      if(IsSpecial(lonBrick.at(0))) continue;
      double lon = lonBrick.at(0) * PI/180.0;

      //Project lat and lon to x and y using a stereographic projection
      double k = 2/(1 + sin(lat_center) * sin(lat) + cos(lat_center)*cos(lat)*cos(lon - lon_center));
      double x = k * cos(lat) * sin(lon - lon_center);
      double y = k * (cos(lat_center) * sin(lat)) - (sin(lat_center) * cos(lat) * cos(lon - lon_center));

      //Add x and y to the least squares matrix
      vector<double> data;
      data.push_back(x);
      data.push_back(y);
      sampSol.AddKnown(data, j);
      lineSol.AddKnown(data, i);

      //If the sample increment goes past the last sample in the line, we want to
      //always read the last sample..
      if(j != inCube->Samples() && j + sinc > inCube->Samples()) {
        j = inCube->Samples() - sinc;
      }
    }
    //If the line increment goes past the last line in the cube, we want to
    //always read the last line..
    if(i != inCube->Lines() && i + linc > inCube->Lines()) {    
      i = inCube->Lines() - linc;
    }
  }

  //Solve the least squares functions using QR Decomposition
  sampSol.Solve(LeastSquares::QRD);
  lineSol.Solve(LeastSquares::QRD);

  //If the user wants to save the residuals to a file, create a file and write
  //the column titles to it.
  TextFile oFile;
  if(ui.WasEntered("RESIDUALS")) {
    oFile.Open(ui.GetFilename("RESIDUALS"), "overwrite");
    oFile.PutLine("Sample,\tLine,\tX,\tY,\tSample Error,\tLine Error\n");
  }

  //Gather the statistics for the residuals from the least squares solutions
  Statistics sampErr;
  Statistics lineErr;
  vector<double> sampResiduals = sampSol.Residuals();
  vector<double> lineResiduals = lineSol.Residuals();
  for(int i = 0; i < (int)sampResiduals.size(); i++) {
    sampErr.AddData(sampResiduals[i]);
    lineErr.AddData(lineResiduals[i]);
  }

  //If a residuals file was specified, write the previous data, and the errors to the file.
  if(ui.WasEntered("RESIDUALS")) {
    for(int i = 0; i < sampSol.Rows(); i++) {
      vector<double> data = sampSol.GetInput(i);
      iString tmp = "";
      tmp += iString(sampSol.GetExpected(i));
      tmp += ",\t";
      tmp += iString(lineSol.GetExpected(i));
      tmp += ",\t";
      tmp += iString(data[0]);
      tmp += ",\t";
      tmp += iString(data[1]);
      tmp += ",\t";
      tmp += iString(sampResiduals[i]);
      tmp += ",\t";
      tmp += iString(lineResiduals[i]);
      oFile.PutLine(tmp + "\n");
    }
  }
  oFile.Close();

  //Records the error to the log
  PvlGroup error( "Error" );
  error += PvlKeyword( "Degree", degree );
  error += PvlKeyword( "NumberOfPoints", (int)sampResiduals.size() );
  error += PvlKeyword( "SampleMinimumError", sampErr.Minimum() );
  error += PvlKeyword( "SampleAverageError", sampErr.Average() );
  error += PvlKeyword( "SampleMaximumError", sampErr.Maximum() );
  error += PvlKeyword( "SampleStdDeviationError", sampErr.StandardDeviation() );
  error += PvlKeyword( "LineMinimumError", lineErr.Minimum() );
  error += PvlKeyword( "LineAverageError", lineErr.Average() );
  error += PvlKeyword( "LineMaximumError", lineErr.Maximum() );
  error += PvlKeyword( "LineStdDeviationError", lineErr.StandardDeviation() );
  Application::Log( error );

  //Close the input cubes for cleanup
  p.EndProcess();

  //If we want to warp the image, then continue, otherwise return
  if(!ui.GetBoolean("NOWARP")) {
    //Creates the mapping group
    Pvl mapFile;
    mapFile.Read(ui.GetFilename("MAP"));
    PvlGroup &mapGrp = mapFile.FindGroup("Mapping",Pvl::Traverse);

    //Reopen the lat and long cubes
    latCube = new Cube();
    latCube->SetVirtualBands(ui.GetInputAttribute("LATCUB").Bands());
    latCube->Open(ui.GetFilename("LATCUB"));

    lonCube = new Cube();
    lonCube->SetVirtualBands(ui.GetInputAttribute("LONCUB").Bands());
    lonCube->Open(ui.GetFilename("LONCUB"));

    PvlKeyword targetName;

    //If the user entered the target name
    if(ui.WasEntered("TARGET")) {
      targetName = PvlKeyword("TargetName", ui.GetString("TARGET"));
    }
    //Else read the target name from the input cube
    else {
      Pvl fromFile;
      fromFile.Read(ui.GetFilename("FROM"));
      targetName = fromFile.FindKeyword("TargetName", Pvl::Traverse);
    }

    mapGrp.AddKeyword(targetName, Pvl::Replace);

    PvlKeyword equRadius;
    PvlKeyword polRadius;


    //If the user entered the equatorial and polar radii
    if(ui.WasEntered("EQURADIUS") && ui.WasEntered("POLRADIUS")) {
      equRadius = PvlKeyword("EquatorialRadius", ui.GetDouble("EQURADIUS"));
      polRadius = PvlKeyword("PolarRadius", ui.GetDouble("POLRADIUS"));
    }
    //Else read them from the pck
    else {
      Filename pckFile("$base/kernels/pck/pck?????.tpc");
      pckFile.HighestVersion();

      string pckFilename = pckFile.Expanded();

      furnsh_c(pckFilename.c_str());

      string target = targetName[0];
      SpiceInt code;
      SpiceBoolean found;

      bodn2c_c (target.c_str(), &code, &found);

      if (!found) {
        string msg = "Could not convert Target [" + target +
                     "] to NAIF code";
        throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_);
      }

      SpiceInt n;
      SpiceDouble radii[3];

      bodvar_c(code,"RADII",&n,radii);

      equRadius = PvlKeyword("EquatorialRadius", radii[0] * 1000);
      polRadius = PvlKeyword("PolarRadius", radii[2] * 1000);
    }

    mapGrp.AddKeyword(equRadius, Pvl::Replace);
    mapGrp.AddKeyword(polRadius, Pvl::Replace);


    //If the latitude type is not in the mapping group, copy it from the input
    if(!mapGrp.HasKeyword("LatitudeType")) {
      if(ui.GetString("LATTYPE") == "PLANETOCENTRIC") {
        mapGrp.AddKeyword(PvlKeyword("LatitudeType","Planetocentric"), Pvl::Replace);
      }
      else {
        mapGrp.AddKeyword(PvlKeyword("LatitudeType","Planetographic"), Pvl::Replace);
      }
    }

    //If the longitude direction is not in the mapping group, copy it from the input
    if(!mapGrp.HasKeyword("LongitudeDirection")) {
      if(ui.GetString("LONDIR") == "POSITIVEEAST") {
        mapGrp.AddKeyword(PvlKeyword("LongitudeDirection","PositiveEast"), Pvl::Replace);
      }
      else {
        mapGrp.AddKeyword(PvlKeyword("LongitudeDirection","PositiveWest"), Pvl::Replace);
      }
    }

    //If the longitude domain is not in the mapping group, assume it is 360
    if(!mapGrp.HasKeyword("LongitudeDomain")) {
      mapGrp.AddKeyword(PvlKeyword("LongitudeDomain","360"), Pvl::Replace);
    }

    //If the default range is to be computed, use the input lat/long cubes to determine the range
    if(ui.GetString("DEFAULTRANGE") == "COMPUTE") {
      //NOTE - When computing the min/max longitude this application does not account for the 
      //longitude seam if it exists. Since the min/max are calculated from the statistics of
      //the input longitude cube and then converted to the mapping group's domain they may be
      //invalid for cubes containing the longitude seam. 
    
      Statistics *latStats = latCube->Statistics();
      Statistics *lonStats = lonCube->Statistics();

      double minLat = latStats->Minimum();
      double maxLat = latStats->Maximum();

      bool isOcentric = ((std::string)mapGrp.FindKeyword("LatitudeType")) == "Planetocentric";
 
      if(isOcentric) {
        if(ui.GetString("LATTYPE") != "PLANETOCENTRIC") {
          minLat = Projection::ToPlanetocentric(minLat, (double)equRadius, (double)polRadius);
          maxLat = Projection::ToPlanetocentric(maxLat, (double)equRadius, (double)polRadius);
        }
      }
      else {
        if(ui.GetString("LATTYPE") == "PLANETOCENTRIC") {
          minLat = Projection::ToPlanetographic(minLat, (double)equRadius, (double)polRadius);
          maxLat = Projection::ToPlanetographic(maxLat, (double)equRadius, (double)polRadius);
        }
      }

      int lonDomain = (int)mapGrp.FindKeyword("LongitudeDomain");
      double minLon = lonDomain == 360 ? Projection::To360Domain(lonStats->Minimum()) : Projection::To180Domain(lonStats->Minimum());
      double maxLon = lonDomain == 360 ? Projection::To360Domain(lonStats->Maximum()) : Projection::To180Domain(lonStats->Maximum());

      bool isPosEast = ((std::string)mapGrp.FindKeyword("LongitudeDirection")) == "PositiveEast";
      
      if(isPosEast) {
        if(ui.GetString("LONDIR") != "POSITIVEEAST") {
          minLon = Projection::ToPositiveEast(minLon, lonDomain);
          maxLon = Projection::ToPositiveEast(maxLon, lonDomain);
        }
      }
      else {
        if(ui.GetString("LONDIR") == "POSITIVEEAST") {
          minLon = Projection::ToPositiveWest(minLon, lonDomain);
          maxLon = Projection::ToPositiveWest(maxLon, lonDomain);
        }
      }

      if(minLon > maxLon) {
        double temp = minLon;
        minLon = maxLon;
        maxLon = temp;
      }

      mapGrp.AddKeyword(PvlKeyword("MinimumLatitude", minLat),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MaximumLatitude", maxLat),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MinimumLongitude", minLon),Pvl::Replace);
      mapGrp.AddKeyword(PvlKeyword("MaximumLongitude", maxLon),Pvl::Replace);
    }

    //If the user decided to enter a ground range then override
    if (ui.WasEntered("MINLAT")) {
      mapGrp.AddKeyword(PvlKeyword("MinimumLatitude",
                                        ui.GetDouble("MINLAT")),Pvl::Replace);
    }
  
    if (ui.WasEntered("MAXLAT")) {
      mapGrp.AddKeyword(PvlKeyword("MaximumLatitude",
                                        ui.GetDouble("MAXLAT")),Pvl::Replace);
    }

    if (ui.WasEntered("MINLON")) {
      mapGrp.AddKeyword(PvlKeyword("MinimumLongitude",
                                        ui.GetDouble("MINLON")),Pvl::Replace);
    }
  
    if (ui.WasEntered("MAXLON")) {
      mapGrp.AddKeyword(PvlKeyword("MaximumLongitude",
                                        ui.GetDouble("MAXLON")),Pvl::Replace);
    }
  
    //If the pixel resolution is to be computed, compute the pixels/degree from the input
    if (ui.GetString("PIXRES") == "COMPUTE") {
      latBrick.SetBasePosition(1,1,1);
      latCube->Read(latBrick);

      lonBrick.SetBasePosition(1,1,1);
      lonCube->Read(lonBrick);

      //Read the lat and long at the upper left corner
      double a = latBrick.at(0) * PI/180.0;
      double c = lonBrick.at(0) * PI/180.0;
  
      latBrick.SetBasePosition(latCube->Samples(),latCube->Lines(),1);
      latCube->Read(latBrick);

      lonBrick.SetBasePosition(lonCube->Samples(),lonCube->Lines(),1);     
      lonCube->Read(lonBrick);

      //Read the lat and long at the lower right corner
      double b = latBrick.at(0) * PI/180.0;
      double d = lonBrick.at(0) * PI/180.0;

      //Determine the angle between the two points
      double angle = acos(cos(a) * cos(b) * cos(c - d) + sin(a) * sin(b));
      //double angle = acos((cos(a1) * cos(b1) * cos(b2)) + (cos(a1) * sin(b1) * cos(a2) * sin(b2)) + (sin(a1) * sin(a2)));
      angle *= 180/PI;

      //Determine the number of pixels between the two points
      double pixels = sqrt(pow(latCube->Samples() -1.0, 2.0) + pow(latCube->Lines() -1.0, 2.0));

      //Add the scale in pixels/degree to the mapping group
      mapGrp.AddKeyword(PvlKeyword("Scale",
                                        pixels/angle, "pixels/degree"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("PixelResolution")) {
        mapGrp.DeleteKeyword("PixelResolution");
      }
    }


    // If the user decided to enter a resolution then override
    if (ui.GetString("PIXRES") == "MPP") {
      mapGrp.AddKeyword(PvlKeyword("PixelResolution",
                                        ui.GetDouble("RESOLUTION"), "meters/pixel"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("Scale")) {
        mapGrp.DeleteKeyword("Scale");
      }
    }
    else if (ui.GetString("PIXRES") == "PPD") {
      mapGrp.AddKeyword(PvlKeyword("Scale",
                                        ui.GetDouble("RESOLUTION"), "pixels/degree"),
                                        Pvl::Replace);
      if (mapGrp.HasKeyword("PixelResolution")) {
        mapGrp.DeleteKeyword("PixelResolution");
      }
    }

    //Create a projection using the map file we created
    int samples,lines;
    Projection *outmap = ProjectionFactory::CreateForCube(mapFile,samples,lines,false);

    //Write the map file to the log
    Application::GuiLog(mapGrp);

    //Create a process rubber sheet
    ProcessRubberSheet r;

    //Set the input cube
    inCube = r.SetInputCube("FROM");

    double tolerance = ui.GetDouble("TOLERANCE") * outmap->Resolution();

    //Create a new transform object
    Transform *transform = new nocam2map (sampSol, lineSol, outmap,
                                          latCube, lonCube,
                                          ui.GetString("LATTYPE") == "PLANETOCENTRIC",
                                          ui.GetString("LONDIR") == "POSITIVEEAST",
                                          tolerance, ui.GetInteger("ITERATIONS"),
                                          inCube->Samples(), inCube->Lines(),
                                          samples, lines);
  
    //Allocate the output cube and add the mapping labels
    Cube *oCube = r.SetOutputCube ("TO", transform->OutputSamples(),
                                              transform->OutputLines(),
                                              inCube->Bands());
    oCube->PutGroup(mapGrp);

    //Determine which interpolation to use
    Interpolator *interp = NULL;
    if (ui.GetString("INTERP") == "NEARESTNEIGHBOR") {
      interp = new Interpolator(Interpolator::NearestNeighborType);
    }
    else if (ui.GetString("INTERP") == "BILINEAR") {
      interp = new Interpolator(Interpolator::BiLinearType);
    }
    else if (ui.GetString("INTERP") == "CUBICCONVOLUTION") {
      interp = new Interpolator(Interpolator::CubicConvolutionType);
    }
  
    //Warp the cube
    r.StartProcess(*transform, *interp);
    r.EndProcess();

    // add mapping to print.prt
    PvlGroup mapping = outmap->Mapping(); 
    Application::Log(mapping); 

    //Clean up
    delete latCube;
    delete lonCube;

    delete outmap;
    delete transform;
    delete interp;
  }
}