Beispiel #1
0
void IsisMain() {

  // Get user interface
  UserInterface &ui = Application::GetUserInterface();

//  Open the shift definitions file
  Pvl shiftdef;
  if (ui.WasEntered("SHIFTDEF")) {
    shiftdef.Read(ui.GetFilename("SHIFTDEF"));
  }
  else {
    shiftdef.AddObject(PvlObject("Hiccdstitch"));
  }

  PvlObject &stitch = shiftdef.FindObject("Hiccdstitch", Pvl::Traverse);


  // Open the first cube.  It will be matched to the second input cube.
  HiJitCube trans;
  CubeAttributeInput &attTrans = ui.GetInputAttribute("FROM");
  vector<string> bandTrans = attTrans.Bands();
  trans.SetVirtualBands(bandTrans);
  trans.OpenCube(ui.GetFilename("FROM"), stitch);

 
  // Open the second cube, it is held in place.  We will be matching the
  // first to this one by attempting to compute a sample/line translation
  HiJitCube match;
  CubeAttributeInput &attMatch = ui.GetInputAttribute("MATCH");
  vector<string> bandMatch = attMatch.Bands();
  match.SetVirtualBands(bandMatch);
  match.OpenCube(ui.GetFilename("MATCH"), stitch);

//  Ensure only one band
  if ((trans.Bands() != 1) || (match.Bands() != 1)) {
    string msg = "Input Cubes must have only one band!";
    throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
  }

//  Now test compatability (basically summing)
  trans.Compatable(match);

//  Determine intersection
  if (!trans.intersects(match)) {
    string msg = "Input Cubes do not overlap!";
    throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_);
  }

//  Get overlapping regions of each cube
  HiJitCube::Corners fcorns, mcorns;
  trans.overlap(match, fcorns);
  match.overlap(trans, mcorns);

#if defined(ISIS_DEBUG)
  cout << "FROM Poly:  " << trans.PolyToString() << std::endl;
  cout << "MATCH Poly: " << match.PolyToString() << std::endl;
  cout << "From Overlap:  (" << fcorns.topLeft.sample << ","
                             << fcorns.topLeft.line   << "), ("
                             << fcorns.lowerRight.sample << "," 
                             << fcorns.lowerRight.line << ")\n" ;
  cout << "Match Overlap: (" << mcorns.topLeft.sample << ","
                             << mcorns.topLeft.line   << "), ("
                             << mcorns.lowerRight.sample << "," 
                             << mcorns.lowerRight.line << ")\n" ;
#endif


  // We need to get a user definition of how to auto correlate around each
  // of the grid points.
  Pvl regdef;
  Filename regFile(ui.GetFilename("REGDEF"));
  regdef.Read(regFile.Expanded());
  AutoReg *ar = AutoRegFactory::Create(regdef);


  double flines(fcorns.lowerRight.line - fcorns.topLeft.line + 1.0);
  double fsamps(fcorns.lowerRight.sample - fcorns.topLeft.sample + 1.0);

  // We want to create a grid of control points that is N rows by M columns.
  // Get row and column variables, if not entered, default to 1% of the input
  // image size
  int rows(1), cols(1);
  if (ui.WasEntered("ROWS")) {
    rows = ui.GetInteger("ROWS");
  }
  else {
    rows = (int)(((flines - 1.0) / ar->SearchChip()->Lines()) + 1);
  }

  cols = ui.GetInteger("COLUMNS");
  if (cols == 0) {
    cols = (int)(((fsamps - 1.0) / ar->SearchChip()->Samples()) + 1);
  }

  // Calculate spacing for the grid of points
  double lSpacing = floor(flines / rows);
  double sSpacing = floor(fsamps / cols);

#if defined(ISIS_DEBUG)
  cout << "# Samples in Overlap: " << fsamps << endl;
  cout << "# Lines in Overlap  : " << flines << endl;
  cout << "# Rows:    " << rows << endl;
  cout << "# Columns: " << cols << endl;
  cout << "Line Spacing:   " << lSpacing << endl;
  cout << "Sample Spacing: " << sSpacing << endl;
#endif

  // Display the progress...10% 20% etc.
  Progress prog;
  prog.SetMaximumSteps(rows * cols);
  prog.CheckStatus();

  // Initialize control point network
  ControlNet cn;
  cn.SetType(ControlNet::ImageToImage);
  cn.SetUserName(Application::UserName());
  cn.SetCreatedDate(iTime::CurrentLocalTime());

  //  Get serial numbers for input cubes
  string transSN = SerialNumber::Compose(trans, true);
  string matchSN = SerialNumber::Compose(match, true);

  cn.SetTarget(transSN);
  cn.SetDescription("Records s/c jitter between two adjacent HiRISE images");

//  Set up results parameter saves
  JitterParms jparms;
  jparms.fromCorns = fcorns;
  jparms.fromJit = trans.GetInfo();
  jparms.matchCorns = mcorns;
  jparms.matchJit = match.GetInfo();
  jparms.regFile =  regFile.Expanded();
  jparms.cols = cols;
  jparms.rows = rows;
  jparms.lSpacing = lSpacing;
  jparms.sSpacing = sSpacing;
  jparms.nSuspects = 0;

  // Loop through grid of points and get statistics to compute
  // translation values
  RegList reglist;
  double fline0(fcorns.topLeft.line-1.0), fsamp0(fcorns.topLeft.sample-1.0);
  double mline0(mcorns.topLeft.line-1.0), msamp0(mcorns.topLeft.sample-1.0);

  for (int r=0; r<rows; r++) {
    int line = (int)(lSpacing / 2.0 + lSpacing * r + 0.5);
    for (int c=0; c<cols; c++) {
      int samp = (int)(sSpacing / 2.0 + sSpacing * c + 0.5);

      ar->PatternChip()->TackCube(msamp0+samp, mline0+line);
      ar->PatternChip()->Load(match);
      ar->SearchChip()->TackCube(fsamp0+samp, fline0+line);
      ar->SearchChip()->Load(trans);

     // Set up ControlMeasure for cube to translate
      ControlMeasure cmTrans;
      cmTrans.SetCubeSerialNumber(transSN);
      cmTrans.SetCoordinate(msamp0+samp, mline0+line, 
                            ControlMeasure::Unmeasured);
      cmTrans.SetChooserName("hijitreg");
      cmTrans.SetReference(false);

      // Set up ControlMeasure for the pattern/Match cube 
      ControlMeasure cmMatch;
      cmMatch.SetCubeSerialNumber(matchSN);
      cmMatch.SetCoordinate(fsamp0+samp, fline0+line, 
                            ControlMeasure::Automatic);
      cmMatch.SetChooserName("hijitreg");
      cmMatch.SetReference(true);


      // Match found
      if (ar->Register()==AutoReg::Success) {
        RegData reg;
        reg.fLine = fline0 + line;
        reg.fSamp = fsamp0 + samp;
        reg.fLTime = trans.getLineTime(reg.fLine);
        reg.mLine = mline0 + line;
        reg.mSamp = msamp0 + samp;
        reg.mLTime = match.getLineTime(reg.mLine);
        reg.regLine = ar->CubeLine();
        reg.regSamp = ar->CubeSample();
        reg.regCorr = ar->GoodnessOfFit();


        if (fabs(reg.regCorr) > 1.0) jparms.nSuspects++;

        double sDiff = reg.fSamp - reg.regSamp;
        double lDiff = reg.fLine - reg.regLine;
        jparms.sStats.AddData(&sDiff,(unsigned int)1);
        jparms.lStats.AddData(&lDiff,(unsigned int)1);

//  Record the translation in the control point
        cmTrans.SetCoordinate(ar->CubeSample(), ar->CubeLine(), 
                              ControlMeasure::Automatic);
        cmTrans.SetError(sDiff, lDiff);
        cmTrans.SetGoodnessOfFit(ar->GoodnessOfFit());

//  Reread the chip location centering the offset and compute
//  linear regression statistics
        try {
          Chip &pchip(*ar->PatternChip());
          Chip fchip(pchip.Samples(), pchip.Lines());
          fchip.TackCube(ar->CubeSample(), ar->CubeLine());
          fchip.Load(trans);

//  Writes correlated chips to files for visual inspection
#if defined(ISIS_DEBUG)
          ostringstream tstr;
          tstr << "R" << r << "C" << c << "_chip.cub";
          string fcname("from"  + tstr.str());
          string mcname("match" + tstr.str());

          pchip.Write(mcname);
          fchip.Write(fcname);
#endif

          MultivariateStatistics mstats;
          for (int line = 1 ; line <= fchip.Lines() ; line++) {
            for(int sample = 1; sample < fchip.Samples(); sample++) {
              double fchipValue = fchip.GetValue(sample,line);
              double pchipValue = pchip.GetValue(sample,line);
              mstats.AddData(&fchipValue, &pchipValue, 1);
            }
          }

//  Get regression and correlation values
          mstats.LinearRegression(reg.B0, reg.B1);
          reg.Bcorr = mstats.Correlation();
          if (IsSpecial(reg.B0)) throw 1;
          if (IsSpecial(reg.B1)) throw 2;
          if (IsSpecial(reg.Bcorr)) throw 3;
        } 
        catch (...) {
//  If fails, flag this condition
          reg.B0 = 0.0;
          reg.B1= 0.0;
          reg.Bcorr = 0.0;
        }

        reglist.push_back(reg);
      }

      // Add the measures to a control point
      string str = "Row " + iString(r) + " Column " + iString(c);
      ControlPoint cp(str);
      cp.SetType(ControlPoint::Tie);
      cp.Add(cmTrans);
      cp.Add(cmMatch);
      if (!cmTrans.IsMeasured()) cp.SetIgnore(true);
      cn.Add(cp);
      prog.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 = ui.GetFilename("FLATFILE");
    ofstream os;
    string fFileExpanded = Filename(fFile).Expanded();
    os.open(fFileExpanded.c_str(),ios::out);
    dumpResults(os, reglist, jparms, *ar);
  }

  // If a cnet file was entered, write the ControlNet pvl to the file
  if (ui.WasEntered("CNETFILE")) {
    cn.Write(ui.GetFilename("CNETFILE"));
  }

  // Don't need the cubes opened anymore
  trans.Close();
  match.Close();


  // Write translation to log
  PvlGroup results("AverageTranslation");
  if (jparms.sStats.ValidPixels() > 0) {
    double sTrans = (int)(jparms.sStats.Average() * 100.0) / 100.0;
    double lTrans = (int)(jparms.lStats.Average() * 100.0) / 100.0;
    results += PvlKeyword ("Sample",sTrans);
    results += PvlKeyword ("Line",lTrans);
    results += PvlKeyword ("NSuspects",jparms.nSuspects);
  }
  else {
    results += PvlKeyword ("Sample","NULL");
    results += PvlKeyword ("Line","NULL");
  }

  Application::Log(results);

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

  return;
}
Beispiel #2
0
void IsisMain() {

  UserInterface &ui = Application::GetUserInterface();

  FileList addList(ui.GetFileName("ADDLIST"));

  bool log = false;
  FileName logFile;
  if (ui.WasEntered("LOG")) {
    log = true;
    logFile = ui.GetFileName("LOG");
  }
  Pvl results;
  results.setName("cnetadd_Results");
  PvlKeyword added("FilesAdded");
  PvlKeyword omitted("FilesOmitted");
  PvlKeyword pointsModified("PointsModified");

  bool checkMeasureValidity = ui.WasEntered("DEFFILE");
  ControlNetValidMeasure validator;
  if (checkMeasureValidity) {
    Pvl deffile(ui.GetFileName("DEFFILE"));
    validator = ControlNetValidMeasure(deffile);
  }

  SerialNumberList *fromSerials = ui.WasEntered("FROMLIST") ?
    new SerialNumberList(ui.GetFileName("FROMLIST")) : new SerialNumberList();

  ControlNet inNet = ControlNet(ui.GetFileName("CNET"));
  inNet.SetUserName(Application::UserName());
  inNet.SetModifiedDate(iTime::CurrentLocalTime()); //This should be done in ControlNet's Write fn

  QString retrievalOpt = ui.GetString("RETRIEVAL");
  PvlKeyword duplicates("DupSerialNumbers");
  if (retrievalOpt == "REFERENCE") {
    FileList list1(ui.GetFileName("FROMLIST"));
    SerialNumberList addSerials(ui.GetFileName("ADDLIST"));

    //Check for duplicate files in the lists by serial number
    for (int i = 0; i < addSerials.Size(); i++) {

      // Check for duplicate SNs accross the lists
      if (fromSerials->HasSerialNumber(addSerials.SerialNumber(i))) {
        duplicates.addValue(addSerials.FileName(i));
      }

      // Check for duplicate SNs within the addlist
      for (int j = i + 1; j < addSerials.Size(); j++) {
        if (addSerials.SerialNumber(i) == addSerials.SerialNumber(j)) {
          QString msg = "Add list files [" + addSerials.FileName(i) + "] and [";
          msg += addSerials.FileName(j) + "] share the same serial number.";
          throw IException(IException::User, msg, _FILEINFO_);
        }
      }
    }

    // Get the lat/long coords from the existing reference measure
    setControlPointLatLon(*fromSerials, inNet);
  }
  else {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      // Get the surface point from the current control point
      ControlPoint *point = inNet.GetPoint(cp);
      SurfacePoint surfacePoint = point->GetBestSurfacePoint();

      if (!surfacePoint.Valid()) {
        QString msg = "Unable to retreive lat/lon from Control Point [";
        msg += point->GetId() + "]. RETREIVAL=POINT cannot be used unless ";
        msg += "all Control Points have Latitude/Longitude keywords.";
        throw IException(IException::User, msg, _FILEINFO_);
      }

      g_surfacePoints[point->GetId()] = surfacePoint;
    }
  }

  FileName outNetFile(ui.GetFileName("ONET"));

  Progress progress;
  progress.SetText("Adding Images");
  progress.SetMaximumSteps(addList.size());
  progress.CheckStatus();

  STRtree coordTree;
  QList<ControlPoint *> pointList;
  bool usePolygon = ui.GetBoolean("POLYGON");
  if (usePolygon) {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      ControlPoint *point = inNet.GetPoint(cp);
      SurfacePoint surfacePoint = g_surfacePoints[point->GetId()];

      Longitude lon = surfacePoint.GetLongitude();
      Latitude lat = surfacePoint.GetLatitude();

      Coordinate *coord = new Coordinate(lon.degrees(), lat.degrees());
      Envelope *envelope = new Envelope(*coord);
      coordTree.insert(envelope, point);
    }
  }
  else {
    for (int cp = 0; cp < inNet.GetNumPoints(); cp++) {
      pointList.append(inNet.GetPoint(cp));
    }
  }

  // Loop through all the images
  for (int img = 0; img < addList.size(); img++) {
    Cube cube;
    cube.open(addList[img].toString());
    Pvl *cubepvl = cube.label();
    QString sn = SerialNumber::Compose(*cubepvl);
    Camera *cam = cube.camera();

    // Loop through all the control points
    QList<ControlPoint *> validPoints = usePolygon ?
        getValidPoints(cube, coordTree) : pointList;

    bool imageAdded = false;
    for (int cp = 0; cp < validPoints.size(); cp++) {
      ControlPoint *point = validPoints[cp];

      // If the point is locked and Apriori source is "AverageOfMeasures"
      // then do not add the measures.
      if (point->IsEditLocked() &&
          point->GetAprioriSurfacePointSource() ==
              ControlPoint::SurfacePointSource::AverageOfMeasures) {
        continue;
      }

      if (point->HasSerialNumber(sn)) continue;

      // Only use the surface point's latitude and longitude, rely on the DEM
      // for computing the radius.  We do this because otherwise we will receive
      // inconsistent results from successive runs of this program if the
      // different DEMs are used, or the point X, Y, Z was generated from the
      // ellipsoid.
      SurfacePoint surfacePoint = g_surfacePoints[point->GetId()];
      if (cam->SetGround(
              surfacePoint.GetLatitude(), surfacePoint.GetLongitude())) {

        // Make sure the samp & line are inside the image
        if (cam->InCube()) {
          ControlMeasure *newCm = new ControlMeasure();
          newCm->SetCoordinate(cam->Sample(), cam->Line(), ControlMeasure::Candidate);
          newCm->SetAprioriSample(cam->Sample());
          newCm->SetAprioriLine(cam->Line());
          newCm->SetCubeSerialNumber(sn);
          newCm->SetDateTime();
          newCm->SetChooserName("Application cnetadd");

          // Check the measure for DEFFILE validity
          if (checkMeasureValidity) {
            if (!validator.ValidEmissionAngle(cam->EmissionAngle())) {
              //TODO: log that it was Emission Angle that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.ValidIncidenceAngle(cam->IncidenceAngle())) {
              //TODO: log that it was Incidence Angle that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.ValidResolution(cam->resolution())) {
              //TODO: log that it was Resolution that failed the check
              newCm->SetIgnored(true);
            }
            else if (!validator.PixelsFromEdge((int)cam->Sample(), (int)cam->Line(), &cube)) {
              //TODO: log that it was Pixels from Edge that failed the check
              newCm->SetIgnored(true);
            }
            else {
              Portal portal(1, 1, cube.pixelType());
              portal.SetPosition(cam->Sample(), cam->Line(), 1);
              cube.read(portal);
              if (!validator.ValidDnValue(portal[0])) {
                //TODO: log that it was DN that failed the check
                newCm->SetIgnored(true);
              }
            }
          }

          point->Add(newCm); // Point takes ownership

          // Record the modified Point and Measure
          g_modifications[point->GetId()].insert(newCm->GetCubeSerialNumber());
          newCm = NULL; // Do not delete because the point has ownership

          if (retrievalOpt == "POINT" && point->GetNumMeasures() == 1)
            point->SetIgnored(false);

          imageAdded = true;
        }
      }
    }

    cubepvl = NULL;
    cam = NULL;

    if (log) {
      PvlKeyword &logKeyword = (imageAdded) ? added : omitted;
      logKeyword.addValue(addList[img].baseName());
    }

    progress.CheckStatus();
  }

  if (log) {
    // Add the list of modified points to the output log file
    QList<QString> modifiedPointsList = g_modifications.keys();
    for (int i = 0; i < modifiedPointsList.size(); i++)
      pointsModified += modifiedPointsList[i];

    results.addKeyword(added);
    results.addKeyword(omitted);
    results.addKeyword(pointsModified);
    if (duplicates.size() > 0) {
      results.addKeyword(duplicates);
    }

    results.write(logFile.expanded());
  }

  // List the modified points
  if (ui.WasEntered("MODIFIEDPOINTS")) {
    FileName pointList(ui.GetFileName("MODIFIEDPOINTS"));

    // Set up the output file for writing
    std::ofstream out_stream;
    out_stream.open(pointList.expanded().toAscii().data(), std::ios::out);
    out_stream.seekp(0, std::ios::beg);   //Start writing from beginning of file

    QList<QString> modifiedPointsList = g_modifications.keys();
    for (int i = 0; i < modifiedPointsList.size(); i++)
      out_stream << modifiedPointsList[i].toStdString() << std::endl;

    out_stream.close();
  }

  // Modify the inNet to only have modified points/measures
  if (ui.GetString("EXTRACT") == "MODIFIED") {
    for (int cp = inNet.GetNumPoints() - 1; cp >= 0; cp--) {
      ControlPoint *point = inNet.GetPoint(cp);

      // If the point was not modified, delete
      // Even get rid of edit locked points in this case
      if (!g_modifications.contains(point->GetId())) {
        point->SetEditLock(false);
        inNet.DeletePoint(cp);
      }
      // Else, remove the unwanted measures from the modified point
      else {
        for (int cm = point->GetNumMeasures() - 1; cm >= 0; cm--) {
          ControlMeasure *measure = point->GetMeasure(cm);

          // Even get rid of edit locked measures in this case
          if (point->GetRefMeasure() != measure &&
              !g_modifications[point->GetId()].contains(
                  measure->GetCubeSerialNumber())) {
            measure->SetEditLock(false);
            point->Delete(cm);
          }
        }
      }
    }
  }

  // Generate the TOLIST if wanted
  if (ui.WasEntered("TOLIST")) {
    SerialNumberList toList;

    SerialNumberList addSerials(ui.GetFileName("ADDLIST"));

    const QList<QString> snList = inNet.GetCubeSerials();
    for (int i = 0; i < snList.size(); i++) {
      QString sn = snList[i];

      if (addSerials.HasSerialNumber(sn))
        toList.Add(addSerials.FileName(sn));
      else if (fromSerials->HasSerialNumber(sn))
        toList.Add(fromSerials->FileName(sn));
    }

    IString name(ui.GetFileName("TOLIST"));
    std::fstream out_stream;
    out_stream.open(name.c_str(), std::ios::out);
    out_stream.seekp(0, std::ios::beg); //Start writing from beginning of file

    for (int f = 0; f < (int) toList.Size(); f++)
      out_stream << toList.FileName(f) << std::endl;

    out_stream.close();
  }

  inNet.Write(outNetFile.expanded());

  delete fromSerials;
}
Beispiel #3
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_);
  }

}
Beispiel #4
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;
}