Beispiel #1
0
  /**
   * FindCnetRef traverses all the control points and measures in the network and checks for
   * valid Measure which passes the Emission Incidence Angle, DN value tests and chooses the
   * measure with the best Resolution criteria as the reference. Creates a new control network
   * with these adjustments.
   *
   * @author Sharmila Prasad (5/25/2010)
   * @history 2010-10-04 Sharmila Prasad - Modified for Binary CNet (Edit Lock)
   *
   * @param pNewNet   - Modified output Control Net
   *
   */
  void CnetRefByResolution::FindCnetRef(ControlNet &pNewNet) {
    // Process each existing control point in the network
    int iPointsModified = 0;
    int iMeasuresModified = 0;
    int iRefChanged = 0;

    //Status Report
    mStatus.SetText("Choosing Reference by Resolution...");
    mStatus.SetMaximumSteps(pNewNet.GetNumPoints());
    mStatus.CheckStatus();

    //mPvlLog += GetStdOptions();
    for (int point = 0; point < pNewNet.GetNumPoints(); ++point) {
      ControlPoint *newPnt = pNewNet.GetPoint(point);
      bool bError = false;
      
      // Create a copy of original control point
      const ControlPoint origPnt(*newPnt);

      mdResVector.clear();

      // Logging
      PvlObject pvlPointObj("PointDetails");
      pvlPointObj += Isis::PvlKeyword("PointId", newPnt->GetId());

      // Edit Lock Option
      bool bPntEditLock = newPnt->IsEditLocked();
      if (!bPntEditLock) {
        newPnt->SetDateTime(Application::DateTime());
      }
      else {
        pvlPointObj += Isis::PvlKeyword("Reference", "No Change, PointEditLock"); 
      }

      int iNumMeasuresLocked = newPnt->GetNumLockedMeasures();
      bool bRefLocked = newPnt->GetRefMeasure()->IsEditLocked();
      int numMeasures = newPnt->GetNumMeasures();
      
      int iRefIndex = -1;
      if (newPnt->IsReferenceExplicit())
        iRefIndex = newPnt->IndexOfRefMeasure();
      QString istrTemp;

      std::vector <PvlGroup> pvlGrpVector;
      int iBestIndex = 0;

      // Only perform the interest operation on points of type "Free" and
      // Points having atleast 1 measure and Point is not Ignored
      // Check for EditLock in the Measures and also verfify that
      // only a Reference Measure can be Locked else error
      if (!newPnt->IsIgnored() && newPnt->GetType() == ControlPoint::Free && numMeasures > 0 &&
          (iNumMeasuresLocked == 0 || (iNumMeasuresLocked > 0 && bRefLocked))) {
        int iNumIgnore = 0;
        QString istrTemp;
        for (int measure = 0; measure < newPnt->GetNumMeasures(); ++measure) {
          ControlMeasure *newMsr = newPnt->GetMeasure(measure);
          bool bMeasureLocked = newMsr->IsEditLocked();
          double dSample      = newMsr->GetSample();
          double dLine        = newMsr->GetLine();
          QString sn      = newMsr->GetCubeSerialNumber();

          if (!bPntEditLock && !bMeasureLocked) {
            newMsr->SetDateTime(Application::DateTime());
            newMsr->SetChooserName("Application cnetref(Resolution)");
          }
         
          // Log
          PvlGroup pvlMeasureGrp("MeasureDetails");
          pvlMeasureGrp += Isis::PvlKeyword("SerialNum", sn);
          pvlMeasureGrp += Isis::PvlKeyword("OriginalLocation", LocationString(dSample, dLine));

          if (bMeasureLocked)
            pvlMeasureGrp += Isis::PvlKeyword("EditLock", "True");

          if (!newMsr->IsIgnored()) {
            Cube *measureCube = mCubeMgr.OpenCube(mSerialNumbers.FileName(sn));
            
            MeasureValidationResults results =
              ValidStandardOptions(newMsr, measureCube, &pvlMeasureGrp);
            if (!results.isValid()) {
              if (bPntEditLock) {
                pvlMeasureGrp += Isis::PvlKeyword("UnIgnored", "Failed Validation Test but not Ignored as Point EditLock is True");
              }
              else if (bMeasureLocked) {
                pvlMeasureGrp += Isis::PvlKeyword("UnIgnored", "Failed Validation Test but not Ignored as Measure EditLock is True");
              }
              else {
                pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Failed Validation Test");
                newMsr->SetIgnored(true);
                iNumIgnore++;
              }
            } // valid measure
            else {
              if (!bPntEditLock && !bRefLocked) {
                newMsr->SetType(ControlMeasure::Candidate);
                newMsr->SetIgnored(false);
                mdResVector.push_back(mdResolution);
              }
            }
          } // Ignore == false
          else {
            pvlMeasureGrp += Isis::PvlKeyword("Ignored", "Originally Ignored");
            iNumIgnore++;
          }
          if (newMsr != origPnt.GetMeasure(measure)) {
            iMeasuresModified++;
          }

          //newPnt.UpdateMeasure(newMsr); // Redesign fixed this
          pvlGrpVector.push_back(pvlMeasureGrp);
        }// end Measure

        if ((newPnt->GetNumMeasures() - iNumIgnore) < 2) {
          if (bPntEditLock) {
            pvlPointObj += Isis::PvlKeyword("UnIgnored", "Good Measures less than 2 but not Ignored as Point EditLock is True");
          }
          else {
            newPnt->SetIgnored(true);
            pvlPointObj += Isis::PvlKeyword("Ignored", "Good Measures less than 2");
          }
        }
        // Set the Reference if the Point is unlocked and Reference measure is unlocked
        if (!newPnt->IsIgnored() && !bPntEditLock && !bRefLocked) {
          iBestIndex = GetReferenceByResolution(newPnt);
          if (iBestIndex >= 0 && !newPnt->GetMeasure(iBestIndex)->IsIgnored()) {
            newPnt->SetRefMeasure(iBestIndex);
            //newPnt.UpdateMeasure(cm); // Redesign fixed this
            pvlGrpVector[iBestIndex] += Isis::PvlKeyword("Reference", "true");
          }
          else {
            if (iBestIndex < 0 && meType == Range) {
              pvlPointObj += Isis::PvlKeyword("NOTE", "No Valid Measures within the Resolution Range. Reference defaulted to the first Measure");
            }
            iBestIndex = 0;
            newPnt->SetRefMeasure(iBestIndex);
            //newPnt.UpdateMeasure(cm); // Redesign fixed this

            // Log info, if Point not locked, apriori source == Reference and a new reference
            if (iRefIndex != iBestIndex &&
                newPnt->GetAprioriSurfacePointSource() == ControlPoint::SurfacePointSource::Reference) {
              pvlGrpVector[iBestIndex] += Isis::PvlKeyword("AprioriSource", "Reference is the source and has changed");
            }
          }
        }

        for (int i = 0; i < newPnt->GetNumMeasures(); i++) {
          pvlPointObj += pvlGrpVector[i];
        }
      } // end Free
      else {
        int iComment = 0;
        if (numMeasures == 0) {
          QString sComment = "Comment";
          sComment += QString(++iComment);
          pvlPointObj += Isis::PvlKeyword(sComment, "No Measures in the Point");
        }

        if (newPnt->IsIgnored()) {
          QString sComment = "Comment";
          sComment += QString(++iComment);
          pvlPointObj += Isis::PvlKeyword(sComment, "Point was originally Ignored");
        }

        if (newPnt->GetType() == ControlPoint::Fixed) {
          QString sComment = "Comment";
          sComment += QString(++iComment);
          pvlPointObj += Isis::PvlKeyword(sComment, "Fixed Point");
        }
        else if (newPnt->GetType() == ControlPoint::Constrained) {
          QString sComment = "Comment";
          sComment += QString(++iComment);
          pvlPointObj += Isis::PvlKeyword(sComment, "Constrained Point");
        }

        if (iNumMeasuresLocked > 0 && !bRefLocked) {
          pvlPointObj += Isis::PvlKeyword("Error", "Point has a Measure with EditLock set to true "
                                          "but the Reference is not Locked");
          bError = true;
        }
        else {
          for (int measure = 0; measure < newPnt->GetNumMeasures(); measure++) {
            ControlMeasure *cm = newPnt->GetMeasure(iBestIndex);
            cm->SetDateTime(Application::DateTime());
            cm->SetChooserName("Application cnetref(Resolution)");
            //newPnt.UpdateMeasure(cm); // Redesign fixed this
          }
        } 
      }

      if (*newPnt != origPnt) {
        iPointsModified++;
      }
      
      if (!bError && !newPnt->IsIgnored() && newPnt->IsReferenceExplicit() && iBestIndex != iRefIndex 
          && !bPntEditLock && !bRefLocked) {
        iRefChanged++;
        PvlGroup pvlRefChangeGrp("ReferenceChangeDetails");
        if (iRefIndex >= 0) {
          pvlRefChangeGrp += Isis::PvlKeyword("PrevSerialNumber",
              origPnt.GetMeasure(iRefIndex)->GetCubeSerialNumber());
          pvlRefChangeGrp += Isis::PvlKeyword("PrevResolution",   toString(mdResVector[iRefIndex]));
  
          istrTemp = QString((int)origPnt.GetMeasure(iRefIndex)->GetSample());
          istrTemp += ",";
          istrTemp += QString((int)origPnt.GetMeasure(iRefIndex)->GetLine());
          pvlRefChangeGrp += Isis::PvlKeyword("PrevLocation",     istrTemp);
        }
        else {
          pvlRefChangeGrp += Isis::PvlKeyword("PrevReference", "Not Set");
        }
        
        pvlRefChangeGrp += Isis::PvlKeyword("NewSerialNumber",
            newPnt->GetMeasure(iBestIndex)->GetCubeSerialNumber());
        QString sKeyName = "NewHighestResolution";
        if (meType == Low) {
          sKeyName = "NewLeastResolution";
        }
        else if (meType == Mean) {
          pvlRefChangeGrp += Isis::PvlKeyword("MeanResolution",  toString(GetMeanResolution()));
          sKeyName = "NewResolutionNeartoMean";
        }
        else if (meType == Nearest) {
          sKeyName = "NewResolutionNeartoValue";
        }
        else if (meType == Range) {
          sKeyName = "NewResolutionInRange";
        }
        pvlRefChangeGrp += Isis::PvlKeyword(sKeyName,  toString(mdResVector[iBestIndex]));

        istrTemp = QString((int)newPnt->GetMeasure(iBestIndex)->GetSample());
        istrTemp += ",";
        istrTemp += QString((int)newPnt->GetMeasure(iBestIndex)->GetLine());
        pvlRefChangeGrp += Isis::PvlKeyword("NewLocation",      istrTemp);

        pvlPointObj += pvlRefChangeGrp;
      }
      else {
        pvlPointObj += Isis::PvlKeyword("Reference", "No Change");
      }

      //pNewNet.UpdatePoint(newPnt); // Redesign fixed this
      mPvlLog += pvlPointObj;
      mStatus.CheckStatus();
    }// end Point

    // CnetRef Change Statistics
    mStatisticsGrp += Isis::PvlKeyword("PointsModified",   toString(iPointsModified));
    mStatisticsGrp += Isis::PvlKeyword("ReferenceChanged", toString(iRefChanged));
    mStatisticsGrp += Isis::PvlKeyword("MeasuresModified", toString(iMeasuresModified));

    mPvlLog += mStatisticsGrp;
  }
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() {
  // 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;
}