Exemplo n.º 1
0
void IsisMain() {
  // Create a serial number list
  UserInterface &ui = Application::GetUserInterface();
  QString filename = ui.GetFileName("FROM");
  SerialNumberList serialNumberList;
  serialNumberList.Add(filename);

  // Get the coordinate for updating the camera pointing
  // We will want to make the camera pointing match the lat/lon at this
  // line sample
  double samp1 = ui.GetDouble("SAMP1");
  double line1 = ui.GetDouble("LINE1");
  Latitude lat1(ui.GetDouble("LAT1"), Angle::Degrees);
  Longitude lon1(ui.GetDouble("LON1"), Angle::Degrees);
  Distance rad1;
  if(ui.WasEntered("RAD1")) {
    rad1 = Distance(ui.GetDouble("RAD1"), Distance::Meters);
  }
  else {
    rad1 = GetRadius(ui.GetFileName("FROM"), lat1, lon1);
  }

  // In order to use the bundle adjustment class we will need a control
  // network
  ControlMeasure * m = new ControlMeasure;
  m->SetCubeSerialNumber(serialNumberList.SerialNumber(0));
  m->SetCoordinate(samp1, line1);
//   m->SetType(ControlMeasure::Manual);
  m->SetType(ControlMeasure::RegisteredPixel);

  ControlPoint * p = new ControlPoint;
  p->SetAprioriSurfacePoint(SurfacePoint(lat1, lon1, rad1));
  p->SetId("Point1");
  p->SetType(ControlPoint::Fixed);
  p->Add(m);

  ControlNet cnet;
//  cnet.SetType(ControlNet::ImageToGround);
  cnet.AddPoint(p);

    // We need the target body
    Cube c;
    c.open(filename, "rw");
    //check for target name
    if(c.label()->hasKeyword("TargetName", PvlObject::Traverse)) {
//       c.Label()->findKeyword("TargetName");
      PvlGroup inst = c.label()->findGroup("Instrument", PvlObject::Traverse);
      QString targetName = inst["TargetName"];
      cnet.SetTarget(targetName);
    }
    c.close();

  // See if they wanted to solve for twist
  if(ui.GetBoolean("TWIST")) {
    double samp2 = ui.GetDouble("SAMP2");
    double line2 = ui.GetDouble("LINE2");
    Latitude lat2(ui.GetDouble("LAT2"), Angle::Degrees);
    Longitude lon2(ui.GetDouble("LON2"), Angle::Degrees);
    Distance rad2;
    if(ui.WasEntered("RAD2")) {
      rad2 = Distance(ui.GetDouble("RAD2"), Distance::Meters);
    }
    else {
      rad2 = GetRadius(ui.GetFileName("FROM"), lat2, lon2);
    }

    ControlMeasure * m = new ControlMeasure;
    m->SetCubeSerialNumber(serialNumberList.SerialNumber(0));
    m->SetCoordinate(samp2, line2);
    m->SetType(ControlMeasure::Manual);

    ControlPoint * p = new ControlPoint;
    p->SetAprioriSurfacePoint(SurfacePoint(lat2, lon2, rad2));
    p->SetId("Point2");
    p->SetType(ControlPoint::Fixed);
    p->Add(m);

    cnet.AddPoint(p);
  }

  // Bundle adjust to solve for new pointing
  try {
    BundleAdjust b(cnet, serialNumberList);
    b.SetSolveTwist(ui.GetBoolean("TWIST"));
    //    double tol = ui.GetDouble("TOL");
    //int maxIterations = ui.GetInteger("MAXITS");
    //b.Solve(tol, maxIterations);
    b.SetSolveCmatrix(BundleAdjust::AnglesOnly);
    b.SetSolveSpacecraftPosition(BundleAdjust::Nothing);
    b.SetErrorPropagation(false);
    b.SetOutlierRejection(false);
    b.SetSolutionMethod("SPECIALK");
    b.SetStandardOutput(true);
    b.SetCSVOutput(false);
    b.SetResidualOutput(true);
    b.SetConvergenceThreshold(ui.GetDouble("SIGMA0"));
    b.SetMaxIterations(ui.GetInteger("MAXITS"));

    b.SetDecompositionMethod(BundleAdjust::SPECIALK);
    b.SolveCholesky();

    Cube c;
    c.open(filename, "rw");

    //check for existing polygon, if exists delete it
    if(c.label()->hasObject("Polygon")) {
      c.label()->deleteObject("Polygon");
    }

    Table cmatrix = b.Cmatrix(0);

    // Write out a description in the spice table
    QString deltackComment = "deltackAdjusted = " + Isis::iTime::CurrentLocalTime();
    cmatrix.Label().addComment(deltackComment);
    //PvlKeyword description("Description");
    //description = "Camera pointing updated via deltack application";
    //cmatrix.Label().findObject("Table",Pvl::Traverse).addKeyword(description);

    // Update the cube history
    c.write(cmatrix);
    History h("IsisCube");
    c.read(h);
    h.AddEntry();
    c.write(h);
    c.close();
    PvlGroup gp("DeltackResults");
    gp += PvlKeyword("Status", "Camera pointing updated");
    Application::Log(gp);
  }
  catch(IException &e) {
    QString msg = "Unable to update camera pointing for [" + filename + "]";
    throw IException(e, IException::Unknown, msg, _FILEINFO_);
  }

}
Exemplo n.º 2
0
void IsisMain() {
  // Get user interface
  UserInterface &ui = Application::GetUserInterface();

  bool register_ignored = ui.GetBoolean("REGISTERIGNOREDONLY");

  // Open the files list in a SerialNumberList for
  // reference by SerialNumber
  SerialNumberList files(ui.GetFilename("FILES"));

  // Create a ControlNet from the input file
  ControlNet inNet(ui.GetFilename("CNET"));

  // Create an AutoReg from the template file
  Pvl pvl(ui.GetFilename("TEMPLATE"));
  AutoReg *ar = AutoRegFactory::Create(pvl);

  // Create the output ControlNet
  ControlNet outNet;
  outNet.SetType(inNet.Type());
  outNet.SetUserName(Application::UserName());
  outNet.SetDescription(inNet.Description());
  outNet.SetCreatedDate(iTime::CurrentLocalTime());
  outNet.SetTarget(inNet.Target());
  outNet.SetNetworkId(inNet.NetworkId());

  Progress progress;
  progress.SetMaximumSteps(inNet.Size());
  progress.CheckStatus();

  int ignored=0, unmeasured=0, registered=0, unregistered=0, validated=0;

  CubeManager cubeMgr;
  cubeMgr.SetNumOpenCubes(50);

  // Register the points and create a new
  // ControlNet containing the refined measurements
  for (int i=0; i<inNet.Size(); i++) {
    ControlPoint &inPoint = inNet[i];

    ControlPoint outPoint;
    outPoint.SetType(inPoint.Type());
    outPoint.SetId(inPoint.Id());
    outPoint.SetUniversalGround(inPoint.UniversalLatitude(), inPoint.UniversalLongitude(), inPoint.Radius());
    outPoint.SetHeld(inPoint.Held());
    outPoint.SetIgnore(inPoint.Ignore());

    // CHECK TO SEE IF THE CONTROL POINT SHOULD BE REGISTERED

    // "Ignore" point and we are not registering ignored
    if (inPoint.Ignore() && !register_ignored){
      ignored++;
      // add "Ignored" to network only if indicated
      if (ui.GetBoolean("OUTPUTIGNORED")) {
        // only include appropriate control measures
        for (int j = 0; j < inPoint.Size(); j++) {
          if (inPoint[j].IsMeasured()){
            outPoint.Add(inPoint[j]); 
          } 
          else{
            unmeasured++;
            if (ui.GetBoolean("OUTPUTUNMEASURED")){
              outPoint.Add(inPoint[j]); 
            } 
          }
        }
        // only add this point if OUTPUTIGNORED
        outNet.Add(outPoint);
      }
      // go to next control point
      continue;
    }
    // Not "Ignore" point (i.e. "valid") and we are only registering "Ignored"
    else if (!inPoint.Ignore() && register_ignored) {
      // add all "valid" points to network
      // only include appropriate control measures
      for (int j = 0; j < inPoint.Size(); j++) {
        if (inPoint[j].IsMeasured()){
          outPoint.Add(inPoint[j]); 
        } 
        else{
          unmeasured++;
          if (ui.GetBoolean("OUTPUTUNMEASURED")) {
            outPoint.Add(inPoint[j]);
          } 
        }
      }
      // add this point since it is not ignored
      outNet.Add(outPoint);
      // go to next control point
      continue;
    }
    // "Ignore" point or "valid" point to be registered
    else { // if ( (inPoint.Ignore() && register_ignored) || (!inPoint.Ignore() && !register_ignored ) ) {
      if (inPoint.Ignore()) { outPoint.SetIgnore(false); }
      
      ControlMeasure &patternCM = inPoint[inPoint.ReferenceIndex()];
      Cube &patternCube = *cubeMgr.OpenCube(files.Filename(patternCM.CubeSerialNumber()));
      
      ar->PatternChip()->TackCube(patternCM.Sample(), patternCM.Line());
      ar->PatternChip()->Load(patternCube);
      
      if (patternCM.IsValidated()) validated++;
      if (!patternCM.IsMeasured()) continue;
      if(!patternCM.IsReference()) {
        patternCM.SetReference(true);
        patternCM.SetChooserName("Application pointreg");
        patternCM.SetDateTime();
      }
      outPoint.Add(patternCM);
      
      // reset goodMeasureCount for this point before looping measures
      int goodMeasureCount = 0; 
      // Register all the unvalidated measurements
      for (int j = 0; j < inPoint.Size(); j++) {
        // don't register the reference, go to next measure
        if (j == inPoint.ReferenceIndex()){
          if (!inPoint[j].Ignore()) goodMeasureCount++;
          continue;
        }
        // if the measurement is valid, keep it as is and go to next measure
        if (inPoint[j].IsValidated()) {
          validated++;
          outPoint.Add(inPoint[j]);
          if (!inPoint[j].Ignore()) goodMeasureCount++;
          continue;
        }
        // if the point is unmeasured, add to output only if necessary and go to next measure
        if (!inPoint[j].IsMeasured()) {
          unmeasured++;
          if (ui.GetBoolean("OUTPUTUNMEASURED")) {
            outPoint.Add(inPoint[j]);
          }
          continue;
        }
      
        ControlMeasure searchCM = inPoint[j];
      
        // refresh pattern cube pointer to ensure it stays valid
        Cube &patternCube = *cubeMgr.OpenCube(files.Filename(patternCM.CubeSerialNumber()));
        Cube &searchCube = *cubeMgr.OpenCube(files.Filename(searchCM.CubeSerialNumber()));

        ar->SearchChip()->TackCube(searchCM.Sample(), searchCM.Line());
      
        try {
          ar->SearchChip()->Load(searchCube,*(ar->PatternChip()),patternCube);
      
          // If the measurements were correctly registered
          // Write them to the new ControlNet
          AutoReg::RegisterStatus res = ar->Register();
      
          double score1, score2;
          ar->ZScores(score1, score2);
          searchCM.SetZScores(score1, score2);
      
          if(res == AutoReg::Success) {
            registered++;
            searchCM.SetType(ControlMeasure::Automatic);
            searchCM.SetError(searchCM.Sample() - ar->CubeSample(), searchCM.Line() - ar->CubeLine());
            searchCM.SetCoordinate(ar->CubeSample(),ar->CubeLine());
            searchCM.SetGoodnessOfFit(ar->GoodnessOfFit());
            searchCM.SetChooserName("Application pointreg");
            searchCM.SetDateTime();
            searchCM.SetIgnore(false);
            outPoint.Add(searchCM);
            goodMeasureCount++;
          }
          // Else use the original marked as "Estimated"
          else {
            unregistered++;
            searchCM.SetType(ControlMeasure::Estimated);
      
            if(res == AutoReg::FitChipToleranceNotMet) {
              searchCM.SetError(inPoint[j].Sample() - ar->CubeSample(), inPoint[j].Line() - ar->CubeLine());
              searchCM.SetGoodnessOfFit(ar->GoodnessOfFit());
            }
            searchCM.SetChooserName("Application pointreg");
            searchCM.SetDateTime();
            searchCM.SetIgnore(true);
            outPoint.Add(searchCM);
          }
        } catch (iException &e) {
          e.Clear();
          unregistered++;
          searchCM.SetType(ControlMeasure::Estimated);
          searchCM.SetChooserName("Application pointreg");
          searchCM.SetDateTime();
          searchCM.SetIgnore(true);
          outPoint.Add(searchCM);
        }
      }

      // Jeff Anderson put in this test (Dec 2, 2008) to allow for control 
      // points to be good so long as at least two measure could be 
      // registered. When a measure can't be registered to the reference then
      // that measure is set to be ignored where in the past the whole point
      // was ignored
      if (goodMeasureCount < 2) {
        if (!outPoint.Held() && outPoint.Type() != ControlPoint::Ground) {
          outPoint.SetIgnore(true);
        }
      }
      // Otherwise, ignore=false. This is already set at the beginning of the registration process

      // Check to see if the control point has now been assigned
      // to "ignore".  If not, add it to the network. If so, only 
      // add it to the output if the OUTPUTIGNORED parameter is selected
      // 2008-11-14 Jeannie Walldren
      if (!outPoint.Ignore()) {                             
        outNet.Add(outPoint);
      }
      else{                                              
        ignored++;                                   
        if (ui.GetBoolean("OUTPUTIGNORED")) outNet.Add(outPoint);
      }
    }
    progress.CheckStatus();
  }

  // If flatfile was entered, create the flatfile
  // The flatfile is comma seperated and can be imported into an excel
  // spreadsheet
  if (ui.WasEntered("FLATFILE")) {
    string fFile = Filename(ui.GetFilename("FLATFILE")).Expanded();
    ofstream os;
    os.open(fFile.c_str(),ios::out);
    os << "PointId,OriginalMeasurementSample,OriginalMeasurementLine," <<
      "RegisteredMeasurementSample,RegisteredMeasurementLine,SampleDifference," <<
      "LineDifference,ZScoreMin,ZScoreMax,GoodnessOfFit" << endl;
    os << NULL8 << endl;
    for (int i=0; i<outNet.Size(); i++) {
      // get point from output control net and its
      // corresponding point from input control net
      ControlPoint outPoint = outNet[i];
      ControlPoint *inPoint = inNet.Find(outPoint.Id());
      if (outPoint.Ignore()) continue;
      for (int i = 0; i<outPoint.Size();i++) {
        // get measure and find its corresponding measure from input net
        ControlMeasure cmTrans = outPoint[i];
        ControlMeasure cmOrig = (*inPoint)[cmTrans.CubeSerialNumber()];
        double inSamp = cmOrig.Sample();
        double inLine = cmOrig.Line();
        double outSamp = cmTrans.Sample();
        double outLine = cmTrans.Line();
        double sampErr = cmTrans.SampleError();
        double lineErr = cmTrans.LineError();
        double zScoreMin = cmTrans.GetZScoreMin();
        if (fabs(zScoreMin) <= DBL_EPSILON || zScoreMin == NULL8) zScoreMin = 0;
        double zScoreMax = cmTrans.GetZScoreMax();
        if (fabs(zScoreMax) <= DBL_EPSILON || zScoreMax == NULL8) zScoreMax = 0;
        double goodnessOfFit = cmTrans.GoodnessOfFit();
        if (fabs(goodnessOfFit) <= DBL_EPSILON || goodnessOfFit == NULL8) goodnessOfFit = 0;
        string pointId = outPoint.Id();
        
        os << pointId << "," << inSamp << ","
           << inLine << "," << outSamp << ","
           << outLine << "," << sampErr << "," 
           << lineErr << "," << zScoreMin << ","
           << zScoreMax << "," << goodnessOfFit << endl;
      }
    }
  }

  PvlGroup pLog("Points");
  pLog+=PvlKeyword("Ignored", ignored);
  Application::Log(pLog);

  PvlGroup mLog("Measures");
  mLog+=PvlKeyword("Validated", validated);
  mLog+=PvlKeyword("Registered", registered);
  mLog+=PvlKeyword("Unregistered", unregistered);
  mLog+=PvlKeyword("Unmeasured", unmeasured);
  Application::Log(mLog);

  // Log Registration Statistics
  Pvl arPvl = ar->RegistrationStatistics();

  for(int i = 0; i < arPvl.Groups(); i++) {
    Application::Log(arPvl.Group(i));
  }

  // add the auto registration information to print.prt
  PvlGroup autoRegTemplate = ar->RegTemplate(); 
  Application::Log(autoRegTemplate); 

  outNet.Write(ui.GetFilename("TO"));

  delete ar;
}