USGS

Isis 3.0 Object Programmers' Reference

Home

ControlNetFilter.cpp
1 #include "ControlNetFilter.h"
2 
3 #include "Angle.h"
4 #include "Camera.h"
5 #include "CameraFactory.h"
6 #include "ControlMeasure.h"
8 #include "ControlNet.h"
9 #include "ControlCubeGraphNode.h"
10 #include "ControlPoint.h"
11 #include "FileName.h"
12 #include "IString.h"
13 #include "Latitude.h"
14 #include "Longitude.h"
15 #include "PvlGroup.h"
16 #include "SerialNumberList.h"
17 #include "Statistics.h"
18 
19 // for double precision
20 #include <limits>
21 typedef std::numeric_limits< double > dbl;
22 
23 using namespace std;
24 
25 #define UNDEFINED_STATUS 2
26 
27 namespace Isis {
28 
30  extern QString sPointType [];
31 
33  extern QString sBoolean[];
34 
44  ControlNetFilter::ControlNetFilter(ControlNet *pCNet, QString &psSerialNumFile, Progress *pProgress) :
45  ControlNetStatistics(pCNet, psSerialNumFile, pProgress) {
46  mSerialNumFilter = SerialNumberList(psSerialNumFile);
47  }
48 
57  void ControlNetFilter::SetOutputFile(QString psPrintFile) {
58  Isis::FileName outFile(psPrintFile);
59  QString outName(outFile.expanded());
60  mOstm.open(outName.toAscii().data(), std::ios::out);
61  mOstm.precision(dbl::digits10);
62  }
63 
70  mOstm.close();
71  }
72 
73 
83  if ( mCNet->GetPoint(pindex)->IsEditLocked() ) {
84  mCNet->GetPoint(pindex)->SetEditLock(false);
85  }
86  mCNet->DeletePoint(pindex);
87  }
88 
100  QString sn(serialNum);
101  const ControlCubeGraphNode *csn = mCNet->getGraphNode(sn);
102  QList< ControlMeasure * > measures = csn->getMeasures();
103 
104  foreach(ControlMeasure * measure, measures) {
105  bool pointEditFlag = false;
106  QString ptId(measure->Parent()->GetId());
107  ControlPoint * point = mCNet->GetPoint(ptId);
108  if (point->IsEditLocked()) {
109  point->SetEditLock(false);
110  pointEditFlag = true;
111  }
112  ControlMeasure *msr = point->GetMeasure(sn);
113  msr->SetEditLock(false);
114  point->Delete(serialNum);
115  if (pointEditFlag) {
116  point->SetEditLock(true);
117  }
118  }
119  }
120 
127  mOstm << "PointID, PointType, PointIgnored, PointEditLocked, TotalMeasures, MeasuresIgnored, MeasuresEditLocked, ";
128  }
129 
138  mOstm << pcPoint.GetId() << ", " << sPointType[(int)pcPoint.GetType()]
139  << ", " << sBoolean[(int)pcPoint.IsIgnored()] << ", "
140  << sBoolean[(int)pcPoint.IsEditLocked()] << ", "
141  << pcPoint.GetNumMeasures() << ", "
142  << pcPoint.GetNumMeasures() - pcPoint.GetNumValidMeasures() << ", "
143  << pcPoint.GetNumLockedMeasures() << ", ";
144  }
145 
154  mOstm << mSerialNumList.FileName(pcMeasure.GetCubeSerialNumber()) << ", ";
155  mOstm << pcMeasure.GetCubeSerialNumber();
156  }
157 
164  mOstm << "FileName, SerialNumber, ImageTotalPoints, ImagePointsIgnored, ImagePointsEditLocked, ImagePointsFixed, ImagePointsConstrained, ImagePointsFree, ImageConvexHullRatio,";
165  }
166 
175  void ControlNetFilter::PointPixelShiftFilter(const PvlGroup &pvlGrp, bool pbLastFilter){
176  double dLesser = Isis::ValidMaximum;
177  double dGreater = 0;
178 
179  if (pvlGrp.hasKeyword("LessThan")) {
180  dLesser = fabs((double)pvlGrp["LessThan"]);
181  }
182 
183  if (pvlGrp.hasKeyword("GreaterThan")) {
184  dGreater = fabs((double)pvlGrp["GreaterThan"]);
185  }
186 
187  if (dLesser < 0 || dGreater < 0 || dLesser <= dGreater) {
188  string sErrMsg = "Invalid Deffile - Check Point_PixelShift Group\n";
189  throw IException(IException::User, sErrMsg, _FILEINFO_);
190  return;
191  }
192 
193  if (pbLastFilter) {
194  mOstm << "PointID, PointType, PointIgnored, PointEditLocked, FileName, SerialNumber, PixelShift, MeasureType, MeasureIgnored, MeasureEditLocked, Reference, ";
195  mOstm << endl;
196  }
197 
198  int iNumPoints = mCNet->GetNumPoints();
199  for (int i = (iNumPoints - 1); i >= 0; i--) {
200  ControlPoint *cPoint = mCNet->GetPoint(i);
201  int iNumMeasures = cPoint->GetNumMeasures();
202  bool bFilter = true;
203  for (int j = 0; j < iNumMeasures; j++){
204  const ControlMeasure *measure = cPoint->GetMeasure(j);
205  double dPixelShift = measure->GetPixelShift();
206  if (dPixelShift <= dLesser && dPixelShift >= dGreater) {
207  bFilter = false;
208  break;
209  }
210  }
211  if (bFilter) {
212  FilterOutPoint(i);
213  continue;
214  }
215 
216  // Print into output, if it is the last Filter
217  if (pbLastFilter) {
218  for (int j = 0; j < iNumMeasures; j++) {
219  mOstm << cPoint->GetId() << ", " << sPointType[cPoint->GetType()] << ", "
220  << sBoolean[cPoint->IsIgnored()] << ", "
221  << sBoolean[cPoint->IsEditLocked()] << ", ";
222 
223  const ControlMeasure *measure = cPoint->GetMeasure(j);
224  PrintCubeFileSerialNum(*measure);
225  double dPixelShift = measure->GetPixelShift();
226  mOstm << ", " << (dPixelShift == Null ? "Null" : toString(dPixelShift)) << ", "
227  << measure->GetMeasureTypeString() << ", "
228  << sBoolean[measure->IsIgnored()] << ", "
229  << sBoolean[measure->IsEditLocked()] << ", "
230  << sBoolean[cPoint->GetRefMeasure() == measure]
231  << endl;
232  }
233  }
234  }
235 
236  // update the image stats with the changes
238  }
239 
250  void ControlNetFilter::PointNumMeasuresEditLockFilter(const PvlGroup &pvlGrp, bool pbLastFilter){
251  int iLesser = VALID_MAX2;
252  int iGreater = 0;
253 
254  if (pvlGrp.hasKeyword("LessThan")) {
255  iLesser = toInt(pvlGrp["LessThan"][0]);
256  }
257 
258  if (pvlGrp.hasKeyword("GreaterThan")) {
259  iGreater = toInt(pvlGrp["GreaterThan"][0]);
260  }
261 
262  if (iLesser < 0 || iGreater < 0 || iLesser < iGreater) {
263  string sErrMsg = "Invalid Deffile - Check Point_MeasureEditLock Group\n";
264  throw IException(IException::User, sErrMsg, _FILEINFO_);
265  return;
266  }
267 
268  if (pbLastFilter) {
270  mOstm << "FileName, SerialNumber, MeasureType, MeasureIgnored, MeasureEditLocked, Reference" << endl;
271  }
272 
273  int iNumPoints = mCNet->GetNumPoints();
274  for (int i = (iNumPoints - 1); i >= 0; i--) {
275  ControlPoint *cPoint = mCNet->GetPoint(i);
276  int iNumLockedMsr = cPoint->GetNumLockedMeasures();
277  //cerr << cPoint->GetId() << " NumMsrs=" << iNumLockedMsr << endl;
278  if (iNumLockedMsr > iLesser || iNumLockedMsr < iGreater) {
279  FilterOutPoint(i);
280  continue;
281  }
282 
283  int iNumMeasures = cPoint->GetNumMeasures();
284  if (pbLastFilter) {
285  for (int j = 0; j < iNumMeasures; j++) {
286  const ControlMeasure *cm = cPoint->GetMeasure(j);
287  PointStats(*cPoint);
289  mOstm << ", " << cm->GetMeasureTypeString() << ", "
290  << sBoolean[cm->IsIgnored()] << ", "
291  << sBoolean[cm->IsEditLocked()] << ", "
292  << sBoolean[cm == cPoint->GetRefMeasure()]
293  << endl;
294  }
295  }
296  }
297 
298  // update the image stats with the changes
300  }
301 
312  void ControlNetFilter::PointEditLockFilter(const PvlGroup &pvlGrp, bool pbLastFilter){
313  bool editLock = false;
314 
315  if (pvlGrp.hasKeyword("EditLock")) {
316  if(pvlGrp["EditLock"][0] == "1" || IString(pvlGrp["EditLock"][0]).DownCase() == "true")
317  editLock = true;
318  }
319 
320  if (pbLastFilter) {
322  mOstm << endl;
323  }
324 
325  int iNumPoints = mCNet->GetNumPoints();
326  for (int i = (iNumPoints - 1); i >= 0; i--) {
327  ControlPoint *cPoint = mCNet->GetPoint(i);
328  if (cPoint->IsEditLocked() != editLock) {
329  FilterOutPoint(i);
330  continue;
331  }
332 
333  if (pbLastFilter) {
334  int iNumMeasures = cPoint->GetNumMeasures();
335  mOstm << cPoint->GetId() << ", " << sPointType[cPoint->GetType()] << ", "
336  << sBoolean[cPoint->IsIgnored()] << ", "
337  << sBoolean[cPoint->IsEditLocked()] << ", "
338  << iNumMeasures << ", "
339  << (iNumMeasures - cPoint->GetNumValidMeasures()) << ", "
340  << cPoint->GetNumLockedMeasures() << endl;
341  }
342  }
343 
344  // update the image stats with the changes
346  }
347 
359  void ControlNetFilter::PointResMagnitudeFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
360  double dLesser = Isis::ValidMaximum;
361  double dGreater = 0;
362 
363  if (pvlGrp.hasKeyword("LessThan")) {
364  if (pvlGrp["LessThan"][0] != "") {
365  dLesser = fabs((double)pvlGrp["LessThan"]);
366  }
367  }
368 
369  if (pvlGrp.hasKeyword("GreaterThan")) {
370  if (pvlGrp["GreaterThan"][0] != "") {
371  dGreater = fabs((double)pvlGrp["GreaterThan"]);
372  }
373  }
374 
375  if (dLesser < 0 || dGreater < 0 || dLesser < dGreater) {
376  string sErrMsg = "Invalid Deffile - Check Point_ResidualMagnitude Group\n";
377  throw IException(IException::User, sErrMsg, _FILEINFO_);
378  return;
379  }
380 
381  if (pbLastFilter) {
382  mOstm << "PointID, PointType, PointIgnored, PointEditLocked, FileName, SerialNumber, ResidualMagnitude, MeasureType, MeasureIgnored, MeasureEditLocked, Reference, ";
383  mOstm << endl;
384  }
385 
386  int iNumPoints = mCNet->GetNumPoints();
387  for (int i = (iNumPoints - 1); i >= 0; i--) {
388  bool bFilter = true;
389  ControlPoint *cPoint = mCNet->GetPoint(i);
390  int iNumMeasures = cPoint->GetNumMeasures();
391  for (int j = 0; j < iNumMeasures; j++) {
392  const ControlMeasure *measure = cPoint->GetMeasure(j);
393  double dResMag = measure->GetResidualMagnitude();
394  if (dResMag <= dLesser && dResMag >= dGreater) {
395  bFilter = false;
396  break;
397  }
398  }
399 
400  if (bFilter) {
401  FilterOutPoint(i);
402  continue;
403  }
404  // Print into output, if it is the last Filter
405  else if (pbLastFilter) {
406 
407  for (int j = 0; j < iNumMeasures; j++) {
408  mOstm << cPoint->GetId() << ", " << sPointType[cPoint->GetType()] << ", "
409  << sBoolean[cPoint->IsIgnored()] << ", "
410  << sBoolean[cPoint->IsEditLocked()] << ", ";
411 
412  const ControlMeasure *measure = cPoint->GetMeasure(j);
413  PrintCubeFileSerialNum(*measure);
414  double dResMag = measure->GetResidualMagnitude();
415  mOstm << ", " << (dResMag == Null ? "Null" : IString(dResMag) ) << ", "
416  << measure->GetMeasureTypeString() << ", "
417  << sBoolean[measure->IsIgnored()] << ", "
418  << sBoolean[measure->IsEditLocked()] << ", "
419  << sBoolean[cPoint->GetRefMeasure() == measure]
420  << endl;
421  }
422  }
423  }
424 
425  // update the image stats with the changes
427  }
428 
438  void ControlNetFilter::PointIDFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
439  QString sPointIDExpr = pvlGrp["Expression"][0];
440  QString sSeparator("*");
441  QStringList strTokens = sPointIDExpr.split(sSeparator, QString::SkipEmptyParts);
442 
443  int iTokenSize = (int)strTokens.size();
444  int iNumPoints = mCNet->GetNumPoints();
445 #ifdef _DEBUG_
446  odb << "Net Size=" << iNumPoints << endl;
447 #endif
448 
449  if (pbLastFilter) {
451  mOstm << endl;
452  }
453 
454  for (int i = (iNumPoints - 1); i >= 0; i--) {
455  const ControlPoint *cPoint = mCNet->GetPoint(i);
456  QString sPointID = cPoint->GetId();
457  int iPosition = 0;
458  for (int j = (iTokenSize - 1); j >= 0; j--) {
459  int iLen = strTokens[j].length();
460  if (iLen > 0) {
461  int found = sPointID.indexOf(strTokens[j], iPosition);
462  if (found != -1) {
463  iPosition = found + iLen;
464  // End of the expression
465  if (pbLastFilter && j == (iTokenSize - 1)) {
466  // Log into the output file
467  PointStats(*cPoint);
468  mOstm << endl;
469  }
470  }
471  else {
472  FilterOutPoint(i);
473  break;
474  }
475  }
476  }
477  }
478 
479  // update the image stats with the changes
481  }
482 
492  void ControlNetFilter::PointMeasuresFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
493  int iLesser = VALID_MAX2, iGreater = 0;
494 
495  if (pvlGrp.hasKeyword("LessThan")) {
496  if (pvlGrp["LessThan"][0] != "") {
497  iLesser = toInt(pvlGrp["LessThan"][0]);
498  }
499  }
500 
501  if (pvlGrp.hasKeyword("GreaterThan")) {
502  if (pvlGrp["GreaterThan"][0] != "") {
503  iGreater = toInt(pvlGrp["GreaterThan"][0]);
504  }
505  }
506 
507  if (iLesser < 0 || iGreater < 0 || iLesser < iGreater) {
508  string sErrMsg = "Invalid Deffile - Check Point_NumMeasures Group\n";
509  throw IException(IException::User, sErrMsg, _FILEINFO_);
510  return;
511  }
512 
513  if (pbLastFilter) {
515  mOstm << "FileName, SerialNum, MeasureType, MeasureIgnore, MeasureEditLock, Reference" << endl;
516  }
517 
518  int iNumPoints = mCNet->GetNumPoints();
519 
520  for (int i = (iNumPoints - 1); i >= 0; i--) {
521  const ControlPoint *cPoint = mCNet->GetPoint(i);
522  int iNumMeasures = cPoint->GetNumMeasures();
523  if (iNumMeasures > iLesser || iNumMeasures < iGreater) {
524  FilterOutPoint(i);
525  continue;
526  }
527  if (pbLastFilter) {
528  for (int j = 0; j < iNumMeasures; j++) {
529  const ControlMeasure *cm = cPoint->GetMeasure(j);
530  PointStats(*cPoint);
532  mOstm << ", " << cm->GetMeasureTypeString() << ", "
533  << sBoolean[cm->IsIgnored()] << ", "
534  << sBoolean[cm->IsEditLocked()] << ", "
535  << sBoolean[cm == cPoint->GetRefMeasure()]
536  << endl;
537  }
538  }
539  }
540 
541  // update the image stats with the changes
543  }
544 
554  void ControlNetFilter::PointPropertiesFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
555  bool bIgnoredFlag = false;
556  int iSetIgnoreFlag = 0;
557  IString sType = "";
558  IString sTemp = "";
559 
560  if (pvlGrp.hasKeyword("PointType")) {
561  if (pvlGrp["PointType"][0] != "") {
562  sType = pvlGrp["PointType"][0];
563  sType = sType.DownCase(sType);
564  }
565  }
566 
567  if (pvlGrp.hasKeyword("Ignore")) {
568  iSetIgnoreFlag = 1;
569  sTemp = pvlGrp["Ignore"][0];
570  if (sTemp == "1" || sTemp.DownCase() == "true") {
571  bIgnoredFlag = true;
572  }
573  }
574 
575  if (pbLastFilter) {
577  mOstm << endl;
578  }
579 
580  int iNumPoints = mCNet->GetNumPoints();
581 
582  for (int i = (iNumPoints - 1); i >= 0; i--) {
583  const ControlPoint *cPoint = mCNet->GetPoint(i);
584  bool bPointFound = false;
585  bool bIgnored = cPoint->IsIgnored();
586  bool bFixed = (cPoint->GetType() == ControlPoint::Fixed ? true : false);
587  bool bConstrained = (cPoint->GetType() == ControlPoint::Constrained ? true : false);
588  bool bFree = (cPoint->GetType() == ControlPoint::Free ? true : false);
589 
590  if (!iSetIgnoreFlag || bIgnoredFlag == bIgnored) {
591  if (sType == "all" || sType=="") {
592  bPointFound = true;
593  }
594  else if (sType == "fixed" && bFixed) {
595  bPointFound = true;
596  }
597  else if (sType == "constrained" && bConstrained) {
598  bPointFound = true;
599  }
600  else if (sType == "free" && bFree) {
601  bPointFound = true;
602  }
603  }
604 
605  if(!bPointFound) {
606  FilterOutPoint(i);
607  continue;
608  }
609 
610  // Output the Point Stats
611  if (pbLastFilter) {
612  PointStats(*cPoint);
613  mOstm << endl;
614  }
615  }
616 
617  // update the image stats with the changes
619  }
620 
630  void ControlNetFilter::PointLatLonFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
631  double dMinLat = Isis::ValidMinimum, dMaxLat = Isis::ValidMaximum;
632  double dMinLon = Isis::ValidMinimum, dMaxLon = Isis::ValidMaximum;
633 
634  if (pvlGrp.hasKeyword("MinLat")) {
635  if (pvlGrp["MinLat"][0] != "") {
636  dMinLat = pvlGrp["MinLat"];
637  }
638  }
639 
640  if (pvlGrp.hasKeyword("MaxLat")) {
641  if (pvlGrp["MaxLat"][0] != "") {
642  dMaxLat = pvlGrp["MaxLat"];
643  }
644  }
645 
646  if (pvlGrp.hasKeyword("MinLon")) {
647  if (pvlGrp["MinLon"][0] != "") {
648  dMinLon = pvlGrp["MinLon"];
649  }
650  }
651 
652  if (pvlGrp.hasKeyword("MaxLon")) {
653  if (pvlGrp["MaxLon"][0] != "") {
654  dMaxLon = pvlGrp["MaxLon"];
655  }
656  }
657 
658  if (dMinLat > dMaxLat || dMinLon > dMaxLon) {
659  string sErrMsg = "Invalid Deffile - Check Point_LatLon Group\n";
660  throw IException(IException::User, sErrMsg, _FILEINFO_);
661  return;
662  }
663 
664  if (pbLastFilter) {
666  mOstm << "Latitude, Longitude, Radius" << endl;
667  }
668 
669  int iNumPoints = mCNet->GetNumPoints();
670 
671  for (int i = (iNumPoints - 1); i >= 0; i--) {
672  const ControlPoint *cPoint = mCNet->GetPoint(i);
673  SurfacePoint cPointSurfPt = cPoint->GetAdjustedSurfacePoint();
674 
675  if (!cPointSurfPt.Valid()) {
676  const ControlMeasure *cm = cPoint->GetRefMeasure();
677 
678  QString sn = cm->GetCubeSerialNumber();
679  QString filename = mSerialNumList.FileName(sn);
680  Cube cube(filename, "r");
681 
682  Camera *camera = CameraFactory::Create(cube);
683  if (camera->SetImage(cm->GetSample(), cm->GetLine())) {
684  cPointSurfPt.SetSpherical(
687  Distance(camera->LocalRadius()));
688  }
689  }
690  double latitude = cPointSurfPt.GetLatitude().degrees();
691  double longitude = cPointSurfPt.GetLongitude().degrees();
692 
693  if ((latitude < dMinLat || latitude > dMaxLat) ||
694  (longitude < dMinLon ||longitude > dMaxLon)) {
695  FilterOutPoint(i);
696  continue;
697  }
698 
699  if (pbLastFilter) {
700  PointStats(*cPoint);
701  mOstm << latitude << ", " << longitude << ", " <<
702  cPointSurfPt.GetLocalRadius().meters() << endl;
703  }
704  }
705 
706  // update the image stats with the changes
708  }
709 
719  void ControlNetFilter::PointDistanceFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
720  double dMaxDistance = 0;
721  QString sUnits = "pixels";
722 
723  if (pvlGrp.hasKeyword("MaxDistance")) {
724  if (pvlGrp["MaxDistance"][0] != "") {
725  dMaxDistance = pvlGrp["MaxDistance"];
726  }
727  }
728 
729  if (pvlGrp.hasKeyword("Units")) {
730  sUnits = pvlGrp["Units"][0];
731  }
732 
733  if (pbLastFilter) {
735  mOstm << "Point#Distance >>, " << endl;
736  }
737 
738  bool bMinDistance = false;
739  int iNumPoints = mCNet->GetNumPoints();
740  for (int i = (iNumPoints - 1); i >= 0; i--) {
741  const ControlPoint *cp1 = mCNet->GetPoint(i);
742  const ControlMeasure *cp1RefMeasure = cp1->GetRefMeasure();
743  SurfacePoint surfacePt1;
744  Camera *cam1;
745 
746  double dSample1 = Isis::Null, dLine1 = Isis::Null;
747 
748  if (sUnits == "meters") {
749  surfacePt1 = cp1->GetAdjustedSurfacePoint();
750 
751  if (!surfacePt1.Valid()) {
752  QString sn1 = cp1RefMeasure->GetCubeSerialNumber();
753  QString filename1 = mSerialNumList.FileName(sn1);
754  Cube cube1(filename1, "r");
755  cam1 = CameraFactory::Create(cube1);
756  if (cam1->SetImage(cp1RefMeasure->GetSample(),
757  cp1RefMeasure->GetLine())) {
758  surfacePt1.SetSpherical(
761  Distance(cam1->LocalRadius())
762  );
763  }
764  }
765  }
766  else
767  // pixels
768  {
769  dSample1 = cp1RefMeasure->GetSample();
770  dLine1 = cp1RefMeasure->GetLine();
771  }
772 
773  for (int j = (mCNet->GetNumPoints() - 1); j >= 0; j--) {
774  if (i == j) {
775  continue;
776  }
777  const ControlPoint *cp2 = mCNet->GetPoint(j);
778  const ControlMeasure *cp2RefMeasure = cp2->GetRefMeasure();
779 
780  SurfacePoint surfacePt2;
781  Camera *cam2;
782  double dDist = 0;
783 
784  double dSample2 = Isis::Null, dLine2 = Isis::Null;
785 
786  if (sUnits == "meters") {
787  surfacePt2 = cp2->GetAdjustedSurfacePoint();
788 
789  if (!surfacePt2.Valid()) {
790  QString sn2 = cp2RefMeasure->GetCubeSerialNumber();
791  QString filename2 = mSerialNumList.FileName(sn2);
792  Cube cube2(filename2, "r");
793  cam2 = CameraFactory::Create(cube2);
794 
795  if (cam2->SetImage(cp2RefMeasure->GetSample(),
796  cp2RefMeasure->GetLine())) {
797  surfacePt2.SetSpherical(
800  Distance(cam2->LocalRadius())
801  );
802  }
803  }
804 
805  dDist = surfacePt1.GetDistanceToPoint(surfacePt2,
806  surfacePt1.GetLocalRadius()).meters();
807  }
808  else
809  // pixels
810  {
811  dSample2 = cp2RefMeasure->GetSample();
812  dLine2 = cp2RefMeasure->GetLine();
813 
814  double dDeltaSamp = dSample1 - dSample2;
815  double dDeltaLine = dLine1 - dLine2;
816  // use the distance formula for cartesian coordinates
817  dDist = sqrt((dDeltaSamp * dDeltaSamp) + (dDeltaLine * dDeltaLine));
818  }
819 
820  if (dDist <= dMaxDistance) {
821  if (pbLastFilter) {
822  if (!bMinDistance) {
823  PointStats(*cp1);
824  }
825  mOstm << cp2->GetId() << "#" << dDist << ", ";
826  }
827  bMinDistance = true;
828  }
829  else
830  continue;
831  }
832  if (!bMinDistance) {
833  FilterOutPoint(i);
834  }
835  if (pbLastFilter && bMinDistance) {
836  mOstm << endl;
837  }
838  bMinDistance = false;
839  }
840 
841  // update the image stats with the changes
843  }
844 
858  void ControlNetFilter::PointGoodnessOfFitFilter(const PvlGroup & pvlGrp, bool pbLastFilter){
859  double dLesser=Isis::ValidMaximum, dGreater=0;
860 
861  if (pvlGrp.hasKeyword("LessThan")){
862  if (pvlGrp["LessThan"][0] != "") {
863  dLesser = fabs((double)(pvlGrp["LessThan"]));
864  }
865  }
866 
867  if (pvlGrp.hasKeyword("GreaterThan")){
868  if (pvlGrp["GreaterThan"][0] != "") {
869  dGreater = fabs((double)pvlGrp["GreaterThan"]);
870  }
871  }
872 
873  if (pbLastFilter) {
875  mOstm << "FileName, SerialNumber, GoodnessOfFit, MeasureType, MeasureIgnored, MeasureEditLocked, Reference" << endl;
876  }
877 
878  int iNumPoints = mCNet->GetNumPoints();
879  for (int i=(iNumPoints-1); i>=0; i--) {
880  ControlPoint *cPoint = mCNet->GetPoint(i);
881  int iNumMeasures = cPoint->GetNumMeasures();
882  bool bMatchFlag=false;
883 
884  for (int j=0; j<iNumMeasures; j++) {
885  const ControlMeasure *measure = cPoint->GetMeasure(j);
886  double dMsrGFit= measure->GetLogData(ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
887  if (dMsrGFit >= dGreater && dMsrGFit <= dLesser) {
888  bMatchFlag = true;
889  break;
890  }
891  }
892 
893  if (!bMatchFlag) {
894  FilterOutPoint(i);
895  }
896  else {
897  // Print into output, if it is the last Filter
898  if (pbLastFilter) {
899  int iNumMeasures = cPoint->GetNumMeasures();
900  int iNumMsIgnored = iNumMeasures - cPoint->GetNumValidMeasures();
901  for (int j = 0; j < iNumMeasures; j++) {
902  const ControlMeasure *measure = cPoint->GetMeasure(j);
903  double dMsrGFit= measure->GetLogData(ControlMeasureLogData::GoodnessOfFit).GetNumericalValue();
904 
905  mOstm << cPoint->GetId() << ", " << sPointType[cPoint->GetType()] << ", "
906  << sBoolean[cPoint->IsIgnored()] << ", " << sBoolean[cPoint->IsEditLocked()] << ", "
907  << iNumMeasures << ", " << iNumMsIgnored << ", " << cPoint->GetNumLockedMeasures() << ", ";
908  PrintCubeFileSerialNum(*measure);
909  mOstm << ", " << (dMsrGFit == Null ? "NA" : IString(dMsrGFit)) << ", "
910  << measure->GetMeasureTypeString() << ", "
911  << sBoolean[measure->IsIgnored()] << ", "
912  << sBoolean[measure->IsEditLocked()] << ", "
913  << sBoolean[cPoint->GetRefMeasure() == measure]
914  << endl;
915  }
916  }
917  }
918  }
919 
920  // update the image stats with the changes
922  }
932  void ControlNetFilter::PointMeasurePropertiesFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
933  int iIgnoredFlag = -1;
934  string sType = "";
935  IString isType;
936 
937  if (pvlGrp.hasKeyword("Ignore")) {
938  iIgnoredFlag = 0;
939  if (IString(pvlGrp["Ignore"][0]).DownCase() == "true")
940  iIgnoredFlag = 1;
941  }
942 
943  if (pvlGrp.hasKeyword("MeasureType")) {
944  sType = IString(pvlGrp["MeasureType"][0]).DownCase();
945  }
946 
947  if (pbLastFilter) {
949  mOstm << "FileName, SerialNumber, MeasureIgnored, MeasureType, MeasureEditLocked, Reference," << endl;
950  }
951 
952  int iNumPoints = mCNet->GetNumPoints();
953  for (int i = (iNumPoints - 1); i >= 0; i--) {
954  const ControlPoint *cPoint = mCNet->GetPoint(i);
955 
956  int iNumMeasures = cPoint->GetNumMeasures();
957  int iNotMeasureType = 0;
958  for (int j = 0; j < iNumMeasures; j++) {
959  const ControlMeasure *cMeasure = cPoint->GetMeasure(j);
960  bool bMeasureIgnored = cMeasure->IsIgnored();
961  bool bMeasureFound = false;
962 
963  if (iIgnoredFlag == -1 || bMeasureIgnored == iIgnoredFlag) {
964  if (sType == "all" || sType == "") {
965  bMeasureFound = true;
966  }
967  else if (sType == "candidate" && cMeasure->GetType() == ControlMeasure::Candidate) {
968  bMeasureFound = true;
969  }
970  else if (sType == "manual" && cMeasure->GetType() == ControlMeasure::Manual) {
971  bMeasureFound = true;
972  }
973  else if (sType == "registeredpixel" && cMeasure->GetType() == ControlMeasure::RegisteredPixel) {
974  bMeasureFound = true;
975  }
976  else if (sType == "registeredsubpixel" && cMeasure->GetType() == ControlMeasure::RegisteredSubPixel) {
977  bMeasureFound = true;
978  }
979  }
980  if (bMeasureFound) {
981  if (pbLastFilter) {
982  PointStats(*cPoint);
983  QString sn = cMeasure->GetCubeSerialNumber();
984  mOstm << mSerialNumList.FileName(sn) << ", " << sn << ","
985  << sBoolean[(int) cMeasure->IsIgnored()] << ", "
986  << cMeasure->GetMeasureTypeString() << ", "
987  << sBoolean[cMeasure->IsEditLocked()] << ", "
988  << sBoolean[cPoint->GetRefMeasure() == cMeasure]
989  << endl;
990  }
991  }
992  else
993  iNotMeasureType++;
994  }
995  //cerr << cPoint->GetId() << " NumMeasures=" << iNumMeasures << " NotFound=" << iNotMeasureType << endl;
996  if (iNotMeasureType == iNumMeasures) {
997  FilterOutPoint(i);
998  continue;
999  }
1000  }
1001 
1002  // update the image stats with the changes
1004  }
1005 
1014  void ControlNetFilter::PointCubeNamesFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
1015  std::vector <QString> sCubeNames;
1016 
1017  // Store the Cubenames from the PvlGroup
1018  for (int i = 0; i < pvlGrp.keywords(); i++) {
1019  sCubeNames.push_back(pvlGrp[i][0]);
1020  }
1021 
1022  int size = sCubeNames.size();
1023 
1024  if (pbLastFilter) {
1025  PointStatsHeader();
1026  CubeStatsHeader();
1027  mOstm << "ImageMeasureIgnored, ImageMeasureEditLocked, ";
1028  mOstm << endl;
1029  }
1030 
1031  int iNumPoints = mCNet->GetNumPoints();
1032  for (int i = (iNumPoints - 1); i >= 0; i--) {
1033  const ControlPoint *cPoint = mCNet->GetPoint(i);
1034  int iNumMeasures = cPoint->GetNumMeasures();
1035  int iNumNoMatch = 0;
1036  bool bMatch = false;
1037  for (int j = 0; j < iNumMeasures; j++) {
1038  const ControlMeasure *cMeasure = cPoint->GetMeasure(j);
1039  for (int k = 0; k < size; k++) {
1040  if (cMeasure->GetCubeSerialNumber() == sCubeNames[k]) {
1041  bMatch = true;
1042  break;
1043  }
1044  }
1045  if (!bMatch) {
1046  iNumNoMatch++;
1047  }
1048  }
1049  if (iNumNoMatch == iNumMeasures) {
1050  FilterOutPoint(i);
1051  }
1052  } //end point loop
1053 
1054  // update the image stats with the changes
1056 
1057  // If Last filter print to the output file in the required format
1058  if (pbLastFilter) {
1059  iNumPoints = mCNet->GetNumPoints();
1060  for (int i = 0; i < iNumPoints; i++) {
1061  const ControlPoint *cPoint = mCNet->GetPoint(i);
1062  int iNumMeasures = cPoint->GetNumMeasures();
1063  for (int j = 0; j < iNumMeasures; j++) {
1064  const ControlMeasure *cMeasure = cPoint->GetMeasure(j);
1065 
1066  // Point Details
1067  mOstm << cPoint->GetId() << ", " << sPointType[cPoint->GetType()] << ", "
1068  << sBoolean[cPoint->IsIgnored()] << ", "
1069  << sBoolean[cPoint->IsEditLocked()] << ", "
1070  << iNumMeasures << ", "
1071  << iNumMeasures - cPoint->GetNumValidMeasures() << ", "
1072  << cPoint->GetNumLockedMeasures() << ", ";
1073 
1074  // Image Details
1075  QString sn = cMeasure->GetCubeSerialNumber();
1076  vector <double> imgStats = GetImageStatsBySerialNum(sn);
1077  mOstm << mSerialNumList.FileName(sn) << ", " << sn << ", "
1078  << imgStats[imgTotalPoints] << ", " << imgStats[imgIgnoredPoints] << ", "
1079  << imgStats[imgLockedPoints] << ", " << imgStats[imgFixedPoints] << ", "
1080  << imgStats[imgConstrainedPoints] << ", " << imgStats[imgFreePoints] << ", "
1081  << imgStats[imgConvexHullRatio] << ", "
1082  << sBoolean[cMeasure->IsIgnored()] << ", " << sBoolean[cMeasure->IsEditLocked()] << endl;
1083  }
1084  }
1085  }
1086  }
1087 
1102  void ControlNetFilter::CubeConvexHullFilter(const PvlGroup &pvlGrp, bool pbLastFilter){
1103  double dLesser = Isis::ValidMaximum;
1104  double dGreater = 0;
1105 
1106  if (pvlGrp.hasKeyword("LessThan")) {
1107  if (pvlGrp["LessThan"][0] != "") {
1108  dLesser = fabs((double)pvlGrp["LessThan"]);
1109  }
1110  }
1111 
1112  if (pvlGrp.hasKeyword("GreaterThan")) {
1113  if (pvlGrp["GreaterThan"][0] != "") {
1114  dGreater = fabs((double)pvlGrp["GreaterThan"]);
1115  }
1116  }
1117 
1118  if (dLesser < 0 || dGreater < 0 || dLesser <= dGreater) {
1119  string sErrMsg = "Invalid Deffile - Check Cube_ConvexHullRatio Group\n";
1120  throw IException(IException::User, sErrMsg, _FILEINFO_);
1121  return;
1122  }
1123 
1124  if (pbLastFilter) {
1125  CubeStatsHeader();
1126  mOstm << endl;
1127  }
1128 
1129  int iNumCubes = mSerialNumFilter.Size();
1130 
1131  for (int sn = (iNumCubes - 1); sn >= 0; sn--) {
1132  QString sSerialNum = mSerialNumFilter.SerialNumber(sn);
1133  vector<double> imgStats = GetImageStatsBySerialNum(sSerialNum);
1134  double convexHullRatio = imgStats[imgConvexHullRatio];
1135  if (convexHullRatio < dGreater || convexHullRatio > dLesser){
1136  FilterOutMeasuresBySerialNum(sSerialNum);
1137  mSerialNumFilter.Delete(sSerialNum);
1138  }
1139  else if (pbLastFilter) {
1140  mOstm << mSerialNumFilter.FileName(sSerialNum) << ", " << sSerialNum << ", "
1141  << imgStats[imgTotalPoints] << ", " << imgStats[imgIgnoredPoints] << ", " << imgStats[imgLockedPoints] << ", "
1142  << imgStats[imgFixedPoints] << ", " << imgStats[imgConstrainedPoints] << ", " << imgStats[imgFreePoints] << ", "
1143  << imgStats[imgConvexHullRatio]<< endl;
1144  }
1145  }
1146 
1147  // update the image stats with the changes
1149  }
1150 
1160  void ControlNetFilter::CubeNameExpressionFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
1161  QString sCubeExpr("");
1162  if (pvlGrp.hasKeyword("Expression")) {
1163  sCubeExpr = QString(pvlGrp["Expression"][0]);
1164  }
1165 
1166  QString sSeparator("*");
1167  QStringList strTokens = sCubeExpr.split(sSeparator, QString::SkipEmptyParts);
1168 
1169  int iTokenSize = (int)strTokens.size();
1170  int iNumCubes = mSerialNumFilter.Size();
1171 
1172  if (pbLastFilter) {
1173  CubeStatsHeader();
1174  mOstm << endl;
1175  }
1176 
1177  for (int i = (iNumCubes - 1); i >= 0; i--) {
1178  QString sCubeName = mSerialNumFilter.FileName(i);
1179  QString sSerialNum = mSerialNumFilter.SerialNumber(i);
1180  int iPosition = 0;
1181  for (int j = (iTokenSize - 1); j >= 0; j--) {
1182  int iLen = strTokens[j].length();
1183  if (iLen > 0) {
1184  int found = sSerialNum.indexOf(strTokens[j], iPosition);
1185  if (found != -1) {
1186  iPosition = found + iLen;
1187  // End of the expression - Found
1188  if (j == (iTokenSize - 1)) {
1189  break;
1190  }
1191  }
1192  else {
1193  FilterOutMeasuresBySerialNum(sSerialNum);
1194  mSerialNumFilter.Delete(sSerialNum);
1195  break;
1196  }
1197  }
1198  }
1199  }
1200 
1201  // update the image stats with the changes
1203 
1204  if (pbLastFilter) {
1205  iNumCubes = mSerialNumFilter.Size();
1206  for (int i = 0; i < iNumCubes; i++) {
1207  QString sSerialNum = mSerialNumFilter.SerialNumber(i);
1208 
1209  mOstm << mSerialNumFilter.FileName(i) << ", " << sSerialNum << ", ";
1210  vector<double> imgStats = GetImageStatsBySerialNum(sSerialNum);
1211  mOstm << mSerialNumFilter.FileName(sSerialNum) << ", " << sSerialNum << ", "
1212  << imgStats[imgTotalPoints] << ", " << imgStats[imgIgnoredPoints] << ", " << imgStats[imgLockedPoints] << ", "
1213  << imgStats[imgFixedPoints] << ", " << imgStats[imgConstrainedPoints] << ", " << imgStats[imgFreePoints] << ", "
1214  << imgStats[imgConvexHullRatio]<< endl;
1215  }
1216  }
1217  }
1218 
1228  void ControlNetFilter::CubeNumPointsFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
1229  int iLessPoints = VALID_MAX2, iGreaterPoints = 0;
1230  if (pvlGrp.hasKeyword("LessThan")) {
1231  if (pvlGrp["LessThan"][0] != "") {
1232  iLessPoints = toInt(pvlGrp["LessThan"][0]);
1233  }
1234  }
1235  if (pvlGrp.hasKeyword("GreaterThan")) {
1236  if (pvlGrp["GreaterThan"][0] != "") {
1237  iGreaterPoints = toInt(pvlGrp["GreaterThan"][0]);
1238  }
1239  }
1240 
1241  if (iLessPoints < 0 || iGreaterPoints < 0 || iLessPoints < iGreaterPoints) {
1242  QString sErrMsg = "Invalid Deffile - Check Cube_NumPoints Group\n";
1243  throw IException(IException::User, sErrMsg, _FILEINFO_);
1244  }
1245 
1246  if (pbLastFilter) {
1247  CubeStatsHeader();
1248  mOstm << endl;
1249  }
1250 
1251  int iNumCubes = mSerialNumFilter.Size();
1252 
1253  for (int sn = (iNumCubes - 1); sn >= 0; sn--) {
1254  QString sSerialNum = mSerialNumFilter.SerialNumber(sn);
1255  vector<double> imgStats = GetImageStatsBySerialNum(sSerialNum);
1256  double numPoints = imgStats[imgTotalPoints];
1257  if (numPoints < iGreaterPoints || numPoints > iLessPoints){
1258  FilterOutMeasuresBySerialNum(sSerialNum);
1259  mSerialNumFilter.Delete(sSerialNum);
1260  }
1261  else if (pbLastFilter) {
1262  mOstm << mSerialNumFilter.FileName(sSerialNum) << ", " << sSerialNum << ", "
1263  << imgStats[imgTotalPoints] << ", " << imgStats[imgIgnoredPoints] << ", " << imgStats[imgLockedPoints] << ", "
1264  << imgStats[imgFixedPoints] << ", " << imgStats[imgConstrainedPoints] << ", " << imgStats[imgFreePoints] << ", "
1265  << imgStats[imgConvexHullRatio] << endl;
1266  }
1267  }
1268 
1269  // update the image stats with the changes
1271  }
1272 
1282  void ControlNetFilter::CubeDistanceFilter(const PvlGroup &pvlGrp, bool pbLastFilter) {
1283  double dDistance = 0;
1284  QString sUnits = "pixels";
1285 
1286  if (pvlGrp.hasKeyword("MaxDistance")) {
1287  if (pvlGrp["MaxDistance"][0] != "") {
1288  dDistance = pvlGrp["MaxDistance"];
1289  }
1290  }
1291 
1292  if (pvlGrp.hasKeyword("Units")) {
1293  sUnits = pvlGrp["Units"][0];
1294  }
1295 
1296  if (dDistance <= 0) {
1297  string sErrMsg = "Invalid Deffile - Check Cube_Distance Group\n";
1298  throw IException(IException::User, sErrMsg, _FILEINFO_);
1299  return;
1300  }
1301 
1302  if (pbLastFilter) {
1303  CubeStatsHeader();
1304  mOstm << "Distance_PointIDs >>, " << endl;
1305  }
1306 
1307  int iNumCubes = mSerialNumFilter.Size();
1308  for (int sn = (iNumCubes - 1); sn >= 0; sn--) {
1309  QString sSerialNum = mSerialNumFilter.SerialNumber(sn);
1310  Cube cube(mSerialNumList.FileName(sSerialNum), "r");
1311  Camera *cam = CameraFactory::Create(cube);
1312  double dDist = 0;
1313  bool bMatchDistance = false;
1314 
1315  std::vector <int> sPointIndex1;
1316  std::vector <int> sPointIndex2;
1317  std::vector <double> dPointDistance;
1318 
1319  // Point stats
1320  int iPointsTotal = 0;
1321  int iPointsIgnored = 0;
1322  int iPointsFixed = 0;
1323  int iPointsConstrained = 0;
1324  int iPointsFree = 0;
1325  int iPointsLocked = 0;
1326 
1327  // Reset the vectors
1328  sPointIndex1.clear();
1329  sPointIndex2.clear();
1330  dPointDistance.clear();
1331 
1332  int iNumPoints = mCNet->GetNumPoints();
1333  for (int i = 0; i < iNumPoints; i++) {
1334  const ControlPoint *cPoint1 = mCNet->GetPoint(i);
1335  const ControlMeasure *cMeasure1;
1336  bool bImageFound = false;
1337  int iNumMeasures1 = cPoint1->GetNumMeasures();
1338  for (int j = 0; j < iNumMeasures1; j++) {
1339  cMeasure1 = cPoint1->GetMeasure(j);
1340  if (cMeasure1->GetCubeSerialNumber() == sSerialNum) {
1341  iPointsTotal++;
1342  if (cPoint1->IsIgnored()) {
1343  iPointsIgnored++;
1344  }
1345  if (cPoint1->GetType() == ControlPoint::Fixed) {
1346  iPointsFixed++;
1347  }
1348  if (cPoint1->GetType() == ControlPoint::Constrained) {
1349  iPointsConstrained++;
1350  }
1351  if (cPoint1->GetType() == ControlPoint::Free) {
1352  iPointsFree++;
1353  }
1354  if (cPoint1->IsEditLocked()) {
1355  iPointsLocked++;
1356  }
1357  bImageFound = true;
1358  break;
1359  }
1360  }
1361  if (!bImageFound) {
1362  continue;
1363  }
1364 
1365  //if(cMeasure1.Sample()==0 && cMeasure1.Line()==0) continue;
1366 
1367  // if the user chooses distance in meters, create camera to find lat/lon for this measure
1368  double dRadius = 0, dLat1 = 0, dLon1 = 0;
1369  if (sUnits == "meters") {
1370  // try to set image using sample/line values
1371  if (cam->SetImage(cMeasure1->GetSample(), cMeasure1->GetLine())) {
1372  dRadius = cam->LocalRadius().meters();
1373  dLat1 = cam->UniversalLatitude();
1374  dLon1 = cam->UniversalLongitude();
1375  }
1376  else
1377  continue;
1378  }
1379 
1380  for (int k = (i + 1); k < iNumPoints; k++) {
1381  const ControlPoint *cPoint2 = mCNet->GetPoint(k);
1382  int iNumMeasures2 = cPoint2->GetNumMeasures();
1383  const ControlMeasure *cMeasure2;
1384  bool bImageFound2 = false;
1385 
1386  for (int j = 0; j < iNumMeasures2; j++) {
1387  if (cPoint2->GetMeasure(j)->GetCubeSerialNumber() == sSerialNum) {
1388  cMeasure2 = cPoint2->GetMeasure(j);
1389  bImageFound2 = true;
1390  break;
1391  }
1392  }
1393  if (!bImageFound2 ||
1394  (cMeasure2->GetSample() == 0 && cMeasure2->GetLine() == 0))
1395  continue;
1396 
1397  if (sUnits == "pixels") {
1398  double dDeltaSamp = cMeasure1->GetSample() - cMeasure2->GetSample();
1399  double dDeltaLine = cMeasure1->GetLine() - cMeasure2->GetLine();
1400  // use the distance formula for cartesian coordinates
1401  dDist = sqrt((dDeltaSamp * dDeltaSamp) + (dDeltaLine * dDeltaLine));
1402  }
1403  else
1404  // calculate distance in meters
1405  {
1406  double dLat2 = 0, dLon2 = 0;
1407  if (cam->SetImage(cMeasure2->GetSample(), cMeasure2->GetLine())) {
1408  dLat2 = cam->UniversalLatitude();
1409  dLon2 = cam->UniversalLongitude();
1410  }
1411  else
1412  continue;
1413 
1414  // Calculate the distance between the two points
1415  Latitude lat1(dLat1, Angle::Degrees);
1416  Longitude lon1(dLon1, Angle::Degrees);
1417  Latitude lat2(dLat2, Angle::Degrees);
1418  Longitude lon2(dLon2, Angle::Degrees);
1419  Distance radius(dRadius, Distance::Meters);
1420 
1421  SurfacePoint point1(lat1, lon1, radius);
1422  SurfacePoint point2(lat2, lon2, radius);
1423 
1424  dDist = point1.GetDistanceToPoint(point1, radius).meters();
1425  }
1426  if (!dDist || dDist >= dDistance) {
1427  continue;
1428  }
1429  else {
1430  bMatchDistance = true;
1431  sPointIndex1.push_back(i);
1432  sPointIndex2.push_back(k);
1433  dPointDistance.push_back(dDist);
1434  //break;
1435  }
1436  }// end Loop Point2
1437  //if (bMatchDistance) {
1438  // break;
1439  //}
1440  } //end Loop Point1
1441  if (!bMatchDistance) {
1442  FilterOutMeasuresBySerialNum(sSerialNum);
1443  mSerialNumFilter.Delete(sSerialNum);
1444  }
1445  else if (pbLastFilter) {
1446  vector <double> imgStats = GetImageStatsBySerialNum((sSerialNum));
1447  mOstm << mSerialNumList.FileName(sSerialNum) << ", " << sSerialNum << ", "
1448  << iPointsTotal << ", " << iPointsIgnored << ", " << iPointsLocked << ", "
1449  << iPointsFixed << ", " << iPointsConstrained << ", " << iPointsFree << ", "
1450  << imgStats[ imgConvexHullRatio] << ", ";
1451  for (int j = 0; j < (int)sPointIndex1.size(); j++) {
1452  QString sPointIDDist = toString(dPointDistance[j]);
1453  sPointIDDist += "#";
1454  sPointIDDist += (*mCNet)[sPointIndex1[j]]->GetId();
1455  sPointIDDist += "#";
1456  sPointIDDist += (*mCNet)[sPointIndex2[j]]->GetId();
1457 
1458  mOstm << sPointIDDist << ",";
1459  }
1460  mOstm << endl;
1461  }
1462  delete(cam);
1463  } // end cube loop
1464 
1465  // update the image stats with the changes
1467  }
1468 }
1469