Isis 3.0 Programmer Reference
Back | Home
ControlNet.cpp
1 #include "IsisDebug.h"
2 
3 #include "ControlNet.h"
4 
5 #include <iostream>
6 #include <cmath>
7 #include <sstream>
8 
9 #include <QtAlgorithms>
10 #include <QDebug>
11 #include <QMutex>
12 #include <QMutexLocker>
13 #include <QPair>
14 #include <QQueue>
15 #include <QScopedPointer>
16 #include <QSet>
17 #include <QTime>
18 #include <QVector>
19 
20 #include <boost/numeric/ublas/symmetric.hpp>
21 #include <boost/numeric/ublas/io.hpp>
22 
23 #include "Application.h"
24 #include "CameraFactory.h"
25 #include "ControlMeasure.h"
26 #include "ControlNetFile.h"
27 #include "ControlNetVersioner.h"
28 #include "ControlPoint.h"
29 #include "ControlCubeGraphNode.h"
30 #include "Distance.h"
31 #include "IException.h"
32 #include "iTime.h"
33 #include "Progress.h"
34 #include "SerialNumberList.h"
35 #include "SpecialPixel.h"
36 #include "Statistics.h"
37 #include "Target.h"
38 
39 using namespace std;
40 using namespace boost::numeric::ublas;
41 
42 
43 namespace Isis {
44 
45  void ControlNet::nullify() {
46 
47  points = NULL;
48  cubeGraphNodes = NULL;
49  pointIds = NULL;
50  m_mutex = NULL;
51  }
52 
54  ControlNet::ControlNet() {
55 
56  nullify();
57 
59  cubeGraphNodes = new QHash< QString, ControlCubeGraphNode * >;
60  pointIds = new QStringList;
61 
62  p_invalid = false;
63  m_ownPoints = true;
64  p_created = Application::DateTime();
65  p_modified = Application::DateTime();
66  }
67 
68 
69  ControlNet::ControlNet(const ControlNet &other) {
70 
71  nullify();
72 
74  cubeGraphNodes = new QHash< QString, ControlCubeGraphNode * >;
75  pointIds = new QStringList;
76 
77  for (int cpIndex = 0; cpIndex < other.GetNumPoints(); cpIndex++) {
78  ControlPoint *newPoint = new ControlPoint(*other.GetPoint(cpIndex));
79  AddPoint(newPoint);
80  }
81 
82  m_ownPoints = true;
83 
84  p_targetName = other.p_targetName;
85  p_targetRadii = other.p_targetRadii;
86  p_networkId = other.p_networkId;
87  p_created = other.p_created;
88  p_modified = other.p_modified;
89  p_description = other.p_description;
90  p_userName = other.p_userName;
91  p_invalid = other.p_invalid;
92  p_cameraMap = other.p_cameraMap;
93  p_cameraList = other.p_cameraList;
94  }
95 
96 
103  ControlNet::ControlNet(const QString &ptfile, Progress *progress) {
104 
105  nullify();
106 
108  cubeGraphNodes = new QHash< QString, ControlCubeGraphNode * >;
109  pointIds = new QStringList;
110 
111  p_invalid = false;
112  m_ownPoints = true;
113 
114  try {
115  ReadControl(ptfile, progress);
116  }
117  catch (IException &e) {
118  p_invalid = true;
119  }
120  }
121 
122 
128  ControlNet::~ControlNet() {
129 
130  clear();
131 
132  delete points;
133  delete cubeGraphNodes;
134  delete pointIds;
135 
136  nullify();
137  }
138 
139 
148  void ControlNet::clear() {
149 
150  // Now must also own points to delete them.
151  if (points) {
152  if (GetNumPoints() > 0) {
153  if (m_ownPoints) {
154  QHashIterator<QString, ControlPoint*> i(*points);
155  while (i.hasNext()) {
156  i.next();
157  delete(*points)[i.key()];
158  (*points)[i.key()] = NULL;
159  }
160  }
161  }
162  points->clear();
163  }
164 
165  if (cubeGraphNodes) {
166  QHashIterator< QString, ControlCubeGraphNode * > i(*cubeGraphNodes);
167  while (i.hasNext()) {
168  i.next();
169  delete(*cubeGraphNodes)[i.key()];
170  (*cubeGraphNodes)[i.key()] = NULL;
171  }
172  cubeGraphNodes->clear();
173  }
174 
175  if (pointIds) {
176  pointIds->clear();
177  }
178 
179  return;
180  }
181 
182 
201  QList< ControlPoint * > ControlNet::take() {
202 
203  // First check to see if someone else has taken ownership
204  if (!m_ownPoints) {
205  throw IException(IException::Programmer, "Ownership has already been taken",
206  _FILEINFO_);
207  }
208 
209  QList<ControlPoint *> points = GetPoints();
210  m_ownPoints = false;
211  clear();
212 
213  // Disconnect the parent network reference
214  for (int i = 0; i < points.size(); i++) {
215  points[i]->parentNetwork = NULL;
216  }
217  return (points);
218  }
219 
220 
243  void ControlNet::ReadControl(const QString &filename, Progress *progress) {
244 
245  LatestControlNetFile *fileData = ControlNetVersioner::Read(filename);
246 
247  ControlNetFileHeaderV0002 &header = fileData->GetNetworkHeader();
248  p_networkId = header.networkid().c_str();
249  if (header.has_targetname()) {
250  SetTarget(header.targetname().c_str());
251  }
252  else {
253  SetTarget("");
254  }
255 
256  p_userName = header.username().c_str();
257  p_created = header.created().c_str();
258  p_modified = header.lastmodified().c_str();
259  p_description = header.description().c_str();
260 
261  QList< ControlPointFileEntryV0002 > &fileDataPoints =
262  fileData->GetNetworkPoints();
263 
264  if (fileDataPoints.size() > 0) {
265  if (progress != NULL) {
266  progress->SetText("Loading Control Points...");
267  progress->SetMaximumSteps(fileDataPoints.size());
268  progress->CheckStatus();
269  }
270 
271  ControlPointFileEntryV0002 fileDataPoint;
272  foreach(fileDataPoint, fileDataPoints) {
273  AddPoint(new ControlPoint(fileDataPoint,
274  p_targetRadii[0], p_targetRadii[1], p_targetRadii[2]));
275 
276  if (progress != NULL)
277  progress->CheckStatus();
278  }
279  }
280 
281  delete fileData;
282  fileData = NULL;
283  }
284 
285 
302  void ControlNet::Write(const QString &ptfile, bool pvl) {
303  LatestControlNetFile *fileData = new LatestControlNetFile();
304 
305  ControlNetFileHeaderV0002 &header = fileData->GetNetworkHeader();
306 
307  header.set_networkid(p_networkId.toLatin1().data());
308  header.set_targetname(p_targetName.toLatin1().data());
309  header.set_username(p_userName.toLatin1().data());
310  header.set_created(p_created.toLatin1().data());
311  header.set_lastmodified(p_modified.toLatin1().data());
312  header.set_description(p_description.toLatin1().data());
313 
314  QList< ControlPointFileEntryV0002 > &fileDataPoints =
315  fileData->GetNetworkPoints();
316 
317  for (int i = 0; i < pointIds->size(); i++) {
318  ControlPoint *point = points->value(pointIds->at(i));
319 
320  ControlPointFileEntryV0002 pointFileEntry = point->ToFileEntry();
321  fileDataPoints.append(pointFileEntry);
322  }
323 
324  ControlNetVersioner::Write(ptfile, *fileData, pvl);
325 
326  delete fileData;
327  fileData = NULL;
328  }
329 
330 
339  void ControlNet::AddPoint(ControlPoint *point) {
340  if (!point) {
341  IString msg = "Null pointer passed to ControlNet::AddPoint!";
342  throw IException(IException::Programmer, msg, _FILEINFO_);
343  }
344 
345  if (ContainsPoint(point->GetId())) {
346  IString msg = "ControlPoint must have unique Id";
347  throw IException(IException::Programmer, msg, _FILEINFO_);
348  }
349 
350  QString pointId = point->GetId();
351  points->insert(pointId, point);
352  pointIds->append(pointId);
353 
354  point->parentNetwork = this;
355 
356  // notify control network of new (non-ignored) measures
357  foreach(ControlMeasure * measure, point->getMeasures()) {
358  measureAdded(measure);
359  }
360  emit networkStructureModified();
361  }
362 
363 
377  void ControlNet::measureAdded(ControlMeasure *measure) {
378  if (!measure) {
379  IString msg = "NULL measure passed to "
380  "ControlNet::AddControlCubeGraphNode!";
381  throw IException(IException::Programmer, msg, _FILEINFO_);
382  }
383 
384  ControlPoint *point = measure->Parent();
385  if (!point) {
386  IString msg = "Control measure with NULL parent passed to "
387  "ControlNet::AddControlCubeGraphNode!";
388  throw IException(IException::Programmer, msg, _FILEINFO_);
389  }
390 
391  if (!ContainsPoint(point->GetId())) {
392  QString msg = "ControlNet does not contain the point [";
393  msg += point->GetId() + "]";
394  throw IException(IException::Programmer, msg, _FILEINFO_);
395  }
396 
397  // make sure there is a node for every measure in this measure's parent
398  for (int i = 0; i < point->GetNumMeasures(); i++) {
399  QString sn = point->GetMeasure(i)->GetCubeSerialNumber();
400  if (!cubeGraphNodes->contains(sn)) {
401  cubeGraphNodes->insert(sn, new ControlCubeGraphNode(sn));
402  }
403  }
404 
405  // add the measure to the corresponding node
406  QString serial = measure->GetCubeSerialNumber();
407  ControlCubeGraphNode *node = (*cubeGraphNodes)[serial];
408  node->addMeasure(measure);
409 
410  // in this measure's node add connections to the other nodes reachable from
411  // its point
412  if (!point->IsIgnored() && !measure->IsIgnored()) {
413  for (int i = 0; i < point->GetNumMeasures(); i++) {
414  ControlMeasure *cm = point->GetMeasure(i);
415  if (!cm->IsIgnored()) {
416  QString sn = cm->GetCubeSerialNumber();
417  ControlCubeGraphNode *neighborNode = (*cubeGraphNodes)[sn];
418 
419  if (neighborNode != node) {
420  node->addConnection(neighborNode, point);
421  neighborNode->addConnection(node, point);
422  }
423  }
424  }
425  }
426  }
427 
428 
441  void ControlNet::measureUnIgnored(ControlMeasure *measure) {
442  if (!measure) {
443  IString msg = "NULL measure passed to "
444  "ControlNet::AddControlCubeGraphNode!";
445  throw IException(IException::Programmer, msg, _FILEINFO_);
446  }
447 
448  ControlPoint *point = measure->Parent();
449  if (!point) {
450  IString msg = "Control measure with NULL parent passed to "
451  "ControlNet::AddControlCubeGraphNode!";
452  throw IException(IException::Programmer, msg, _FILEINFO_);
453  }
454 
455  if (!ContainsPoint(point->GetId())) {
456  QString msg = "ControlNet does not contain the point [";
457  msg += point->GetId() + "]";
458  throw IException(IException::Programmer, msg, _FILEINFO_);
459  }
460 
461  // make sure there is a node for every measure in this measure's parent
462  for (int i = 0; i < point->GetNumMeasures(); i++) {
463  QString sn = point->GetMeasure(i)->GetCubeSerialNumber();
464  if (!cubeGraphNodes->contains(sn)) {
465  QString msg = "Node does not exist for [";
466  msg += measure->GetCubeSerialNumber() + "]";
467  throw IException(IException::Programmer, msg, _FILEINFO_);
468  }
469  }
470 
471  if (!point->IsIgnored()) {
472  QString serial = measure->GetCubeSerialNumber();
473  ControlCubeGraphNode *node = (*cubeGraphNodes)[serial];
474 
475  // in this measure's node add connections to the other nodes reachable
476  // from its point
477  for (int i = 0; i < point->GetNumMeasures(); i++) {
478  ControlMeasure *cm = point->GetMeasure(i);
479  if (!cm->IsIgnored()) {
480  QString sn = cm->GetCubeSerialNumber();
481  ControlCubeGraphNode *neighborNode = (*cubeGraphNodes)[sn];
482  if (neighborNode != node) {
483  node->addConnection(neighborNode, point);
484  neighborNode->addConnection(node, point);
485  }
486  }
487  }
488  }
489  }
490 
491 
500  void ControlNet::UpdatePointReference(ControlPoint *point, QString oldId) {
501  points->remove(oldId);
502  (*points)[point->GetId()] = point;
503  (*pointIds)[pointIds->indexOf((QString) oldId)] = (QString)point->GetId();
504  }
505 
506 
514  void ControlNet::measureDeleted(ControlMeasure *measure) {
515  ASSERT(measure);
516 
517  QString serial = measure->GetCubeSerialNumber();
518  ASSERT(cubeGraphNodes->contains(serial));
519  ControlCubeGraphNode *node = (*cubeGraphNodes)[serial];
520 
521  // remove connections to and from this node
522  if (!measure->IsIgnored() && !measure->Parent()->IsIgnored()) {
523  // Break connections
524  measureIgnored(measure);
525  }
526 
527  // Remove the measure from the node. If this caused the node to be empty,
528  // then delete the node.
529  node->removeMeasure(measure);
530  if (!node->getMeasureCount()) {
531  delete node;
532  node = NULL;
533  cubeGraphNodes->remove(serial);
534  }
535  }
536 
537 
538  void ControlNet::measureIgnored(ControlMeasure *measure) {
539  if (!measure) {
540  IString msg = "NULL measure passed to "
541  "ControlNet::AddControlCubeGraphNode!";
542  throw IException(IException::Programmer, msg, _FILEINFO_);
543  }
544 
545  ControlPoint *point = measure->Parent();
546  if (!point) {
547  IString msg = "Control measure with NULL parent passed to "
548  "ControlNet::AddControlCubeGraphNode!";
549  throw IException(IException::Programmer, msg, _FILEINFO_);
550  }
551 
552  QString serial = measure->GetCubeSerialNumber();
553  if (!cubeGraphNodes->contains(serial)) {
554  QString msg = "Node does not exist for [";
555  msg += serial + "]";
556  throw IException(IException::Programmer, msg, _FILEINFO_);
557  }
558 
559  ControlCubeGraphNode *node = (*cubeGraphNodes)[serial];
560 
561  // remove connections to and from this node
562  for (int i = 0; i < point->GetNumMeasures(); i++) {
563  QString sn = point->GetMeasure(i)->GetCubeSerialNumber();
564  if (cubeGraphNodes->contains(sn)) {
565  ControlCubeGraphNode *neighborNode = (*cubeGraphNodes)[sn];
566  if (node != neighborNode) {
567  neighborNode->removeConnection(node, point);
568  node->removeConnection(neighborNode, point);
569  }
570  }
571  }
572  }
573 
574 
575  void ControlNet::emitNetworkStructureModified() {
576  emit networkStructureModified();
577  }
578 
579 
590  QList< ControlCubeGraphNode * > ControlNet::RandomBFS(
591  QList< ControlCubeGraphNode * > nodes) const {
592  qsrand(42);
593  Shuffle(nodes);
594 
595  // for keeping track of visited nodes
597  for (int i = 0; i < nodes.size(); i++)
598  searchList.insert(nodes[i], false);
599 
600  // for storing nodes as they are found
602 
604  q.enqueue(nodes[0]);
605  while (q.size()) {
606  ControlCubeGraphNode *curNode = q.dequeue();
607  if (!results.contains(curNode)) {
608  // add to results
609  results.insert(curNode);
610  searchList[curNode] = true;
611 
612  // add all the neighbors to the queue
613  QList< ControlCubeGraphNode * > neighbors = curNode->getAdjacentNodes();
614  Shuffle(neighbors);
615  for (int i = 0; i < neighbors.size(); i++)
616  q.enqueue(neighbors[i]);
617  }
618  } // end of breadth-first search
619 
620  return results.values();
621  }
622 
623 
629  void ControlNet::Shuffle(QList< ControlCubeGraphNode * > & list) const {
630  for (int i = list.size() - 1; i > 0; i--) {
631  // standard form is qrand() / (RAND_MAX + 1.0) * (max + 1 - min) + min
632  // min is always zero here so it is simplified to...
633  int j = (int)(qrand() / (RAND_MAX + 1.0) * (i + 1));
634  qSwap(list[j], list[i]);
635  }
636  }
637 
638 
653  QPair< int, int > ControlNet::CalcBWAndCE(QList< QString > serials) const {
654 
655  for (int i = 0; i < serials.size(); i++)
656  ASSERT(cubeGraphNodes->contains(serials[i]));
657 
658  int bw = 0;
659  QList< int > colWidths;
660 
661  for (int i = 0; i < serials.size(); i++) {
662  int colWidth = 0;
663  ControlCubeGraphNode *node1 = (*cubeGraphNodes)[serials[i]];
664  for (int j = 0; j < serials.size(); j++) {
665  if (i != j) {
666  ControlCubeGraphNode *node2 = (*cubeGraphNodes)[serials[j]];
667  int colDiff = abs(i - j);
668  if (node1->isConnected(node2) && colDiff > colWidth)
669  colWidth = colDiff;
670  }
671  }
672  colWidths.append(colWidth);
673  if (colWidth > bw)
674  bw = colWidth;
675  }
676 
677  int criticalEdges = 0;
678  foreach(int width, colWidths) {
679  if (width == bw)
680  criticalEdges++;
681  }
682 
683  return qMakePair(bw, criticalEdges);
684  }
685 
686 
692  int ControlNet::DeletePoint(ControlPoint *point) {
693  if (points->values().contains(point)) {
694  return DeletePoint(point->GetId());
695  }
696  else {
697  IString msg = "point [";
698  msg += (long) point;
699  msg += "] does not exist in the network";
700  throw IException(IException::User, msg, _FILEINFO_);
701  }
702  }
703 
704 
712  int ControlNet::DeletePoint(QString pointId) {
713  if (!points->contains(pointId)) {
714  IString msg = "point Id [" + pointId + "] does not exist in the network";
715  throw IException(IException::User, msg, _FILEINFO_);
716  }
717 
718  ControlPoint *point = (*points)[pointId];
719 
720  if (point->IsEditLocked())
721  return ControlPoint::PointLocked;
722 
723  bool wasIgnored = point->IsIgnored();
724 
725  // notify CubeSerialNumbers of the loss of this point
726  foreach(ControlMeasure * measure, point->getMeasures()) {
727  measureDeleted(measure);
728  }
729 
730  // See if removing this point qualifies for a re-check of validity
731  bool check = false;
732  if (p_invalid && point->IsInvalid())
733  check = true;
734 
735  // delete point
736  points->remove(pointId);
737  pointIds->removeAt(pointIds->indexOf(pointId));
738  delete point;
739  point = NULL;
740 
741  // Check validity if needed (There were two or more points with the same
742  // Id - see if this is still the case)
743  if (check) {
744  p_invalid = false;
745 
746  // check for 2 or more points with same Id
747  QList< QString > keys = points->keys();
748  for (int i = 0; i < keys.size() && !p_invalid; i++) {
749  if (points->count(keys[i]) > 1)
750  p_invalid = true;
751  }
752  }
753 
754  if (!wasIgnored)
755  emit networkStructureModified();
756 
757  return ControlPoint::Success;
758  }
759 
760 
766  int ControlNet::DeletePoint(int index) {
767  if (index < 0 || index >= pointIds->size()) {
768  IString msg = "Index [" + IString(index) + "] out of range";
769  throw IException(IException::Programmer, msg, _FILEINFO_);
770  }
771 
772  return DeletePoint(pointIds->at(index));
773  }
774 
775 
781  bool ControlNet::ContainsPoint(QString pointId) const {
782  return points->contains(pointId);
783  }
784 
785 
797  QList< QList< QString > > ControlNet::GetSerialConnections() const {
798  QList< QList< QString > > islandStrings;
799  QList< QList< ControlCubeGraphNode * > > islands = GetNodeConnections();
800  for (int i = 0; i < islands.size(); i++) {
801  QList< QString > newIsland;
802  islandStrings.append(newIsland);
803  for (int j = 0; j < islands[i].size(); j++)
804  islandStrings[i].append(islands[i][j]->getSerialNumber());
805  }
806  return islandStrings;
807  }
808 
809 
821  QList< QList< ControlCubeGraphNode * > > ControlNet::GetNodeConnections() const {
822  QList< ControlCubeGraphNode * > notYetFound = cubeGraphNodes->values();
824 
825  do {
826  // extract an island from the nodes which are not yet found
827  QList< ControlCubeGraphNode * > island = RandomBFS(notYetFound);
828 
829  // remove newly found nodes from notYetFound
830  for (int i = 0; i < island.size(); i++)
831  notYetFound.removeOne(island[i]);
832 
833  // Add island to list of islands
834  islands.append(island);
835  }
836  while (notYetFound.size());
837 
838  return islands;
839  }
840 
841 
887  QSet< ControlMeasure * > ControlNet::MinimumSpanningTree(
889  bool lessThan(const ControlMeasure *, const ControlMeasure *)) const {
890 
891  // Kruskal's Algorithm
892  QSet< ControlMeasure * > minimumTree;
893 
894  // We start with a map containing all the unconnected vertices (nodes and
895  // points), each its own single-element tree. Our goal is join them all
896  // together into one tree connecting every vertex. We map into the forest
897  // with point ID and serial number so the two types of vertices can share a
898  // common, nearly constant-time lookup interface.
900 
901  // Get a list of all the candidate edges on the island, and a set of their
902  // associated Control Points (to avoid duplication, as measures share common
903  // points). Keep a count of how many measures in the MST are connected to
904  // each point, as we'll want to prune off points with only one such
905  // conenction.
907  QMap< ControlPoint *, int > uniquePoints;
908  for (int i = 0; i < island.size(); i++) {
909  // Add each graph node as a tree in the forest
910  ControlCubeGraphNode *node = island[i];
911  forest.insert(node->getSerialNumber(), new ControlVertex(node));
912 
913  // Every graph node has a list of measures: these are our edges
914  QList< ControlMeasure * > measures = node->getMeasures();
915  for (int j = 0; j < measures.size(); j++) {
916  edges.append(measures[j]);
917 
918  // Every measure has a point: these act as intermediate vertices. We
919  // keep a count of how many edges in the MST come off this point.
920  // Points with less than 2 edges are considered incomplete, as they do
921  // not form a connection from one graph node to another, or a "complete
922  // edge"
923  uniquePoints.insert(measures[j]->Parent(), 0);
924  }
925  }
926 
927  // Sort the edges in increasing cost with the provided less-than function
928  qSort(edges.begin(), edges.end(), lessThan);
929 
930  // Add every unique point on the island as a tree in the forest
931  QList< ControlPoint * > pointList = uniquePoints.keys();
932  for (int i = 0; i < pointList.size(); i++) {
933  ControlPoint *point = pointList[i];
934  forest.insert(point->GetId(), new ControlVertex(point));
935  }
936 
937  // Every time we join two trees together, we reduce the total number of
938  // trees by one, but our forest data structure is unchanged, so keep a
939  // record of the actual forest size to decrement manually as we go along
940  int trees = forest.size();
941 
942  // Keep trying to join trees until there is only one tree remaining or we're
943  // out of edges to try
944  while (trees > 1 && edges.size() > 0) {
945  // Try to add our lowest-cost edge to the minimum spanning tree
946  ControlMeasure *leastEdge = edges.takeFirst();
947 
948  // Each edge connects two vertices: a point and a graph node. So grab the
949  // trees for each node and check that they're disjoint, and thus able to
950  // be joined.
951  QString pointId = leastEdge->Parent()->GetId();
952  ControlVertex *pointVertex = forest[pointId];
953 
954  QString serialNum = leastEdge->ControlSN()->getSerialNumber();
955  ControlVertex *nodeVertex = forest[serialNum];
956 
957  // When the edge joins two different trees (i.e., they have different
958  // roots), then add the edge to the minimum spanning tree and join the
959  // trees into one. Otherwise, we have formed a cycle and should thus
960  // discard the edge.
961  if (pointVertex->getRoot() != nodeVertex->getRoot()) {
962  ControlVertex::join(pointVertex, nodeVertex);
963  trees--;
964  minimumTree.insert(leastEdge);
965  uniquePoints[pointVertex->getPoint()]++;
966  }
967  }
968 
969  // Prune edges that go from a graph node to a point, but not from that
970  // point to another graph node. We care about image (graph node)
971  // connectivity, not point connectivity. A complete edge consists of two
972  // measures and a point, so remove any incomplete edges.
973  QList< ControlMeasure * > unprunedEdges = minimumTree.values();
974  for (int i = 0; i < unprunedEdges.size(); i++) {
975  if (uniquePoints[unprunedEdges[i]->Parent()] < 2)
976  // The point this edge is connected to does not go on to another node,
977  // so prune it
978  minimumTree.remove(unprunedEdges[i]);
979  }
980 
981  // Clean up our vertices. This will not delete any of the points, measures,
982  // or graph nodes. All of that is owned by the network.
983  QList< ControlVertex * > vertexList = forest.values();
984  for (int i = 0; i < vertexList.size(); i++) delete vertexList[i];
985 
986  // Sanity check: an island with n > 1 nodes must, by definition, have an MST
987  // of e edges such that n <= e <= 2n
988  int n = island.size();
989  int e = minimumTree.size();
990  if (n > 1) {
991  if (e < n || e > 2 * n) {
992  IString msg = "An island of n = [" + IString(n) +
993  "] > 1 nodes must have a minimum spanning tree of e edges such that "
994  " n <= e <= 2n, but e = [" + IString(e) + "]";
995  throw IException(IException::Programmer, msg, _FILEINFO_);
996  }
997  }
998 
999  return minimumTree;
1000  }
1001 
1002 
1006  int ControlNet::getEdgeCount() const {
1007  int total = 0;
1008  foreach (ControlCubeGraphNode * node, *cubeGraphNodes) {
1009  total += node->getAdjacentNodes().size();
1010  }
1011 
1012  return total;
1013  }
1014 
1015 
1021  QString ControlNet::CubeGraphToString() const {
1022  QStringList serials;
1023  QHashIterator < QString, ControlCubeGraphNode * > i(*cubeGraphNodes);
1024  while (i.hasNext()) {
1025  i.next();
1026  serials << i.value()->getSerialNumber();
1027  }
1028  qSort(serials);
1029 
1030  QString str;
1031  for (int i = 0; i < serials.size(); i++) {
1032  str += " " + serials[i] + "\n"
1033  + (*cubeGraphNodes)[serials[i]]->connectionsToString() + "\n";
1034  }
1035 
1036  return str;
1037  }
1038 
1039 
1048  QList< QString > ControlNet::GetCubeSerials() const {
1049  return cubeGraphNodes->keys();
1050  }
1051 
1052 
1056  QList< ControlCubeGraphNode * > ControlNet::GetCubeGraphNodes() {
1057  return cubeGraphNodes->values();
1058  }
1059 
1060 
1067  void ControlNet::ValidateSerialNumber(QString serialNumber) const {
1068  if (!cubeGraphNodes->contains(serialNumber)) {
1069  IString msg = "Cube Serial Number [" + serialNumber + "] not found in "
1070  "the network";
1071  throw IException(IException::Programmer, msg, _FILEINFO_);
1072  }
1073  }
1074 
1075 
1081  QList< ControlMeasure * > ControlNet::GetMeasuresInCube(QString serialNumber) {
1082  ValidateSerialNumber(serialNumber);
1083  return (*cubeGraphNodes)[serialNumber]->getMeasures();
1084  }
1085 
1086 
1093  ControlNet::ControlMeasureLessThanFunctor::operator=(ControlMeasureLessThanFunctor const &other) {
1094 
1095  if (this != &other) {
1096  this->m_accessor = other.m_accessor;
1097  }
1098 
1099  return *this;
1100  }
1101 
1102 
1109  bool ControlNet::ControlMeasureLessThanFunctor::operator()
1110  (ControlMeasure* const &a, ControlMeasure* const &b) {
1111 
1112  return (a->*this->m_accessor)() < (b->*this->m_accessor)();
1113 
1114  }
1115 
1116 
1124  QList< ControlMeasure * > ControlNet::sortedMeasureList(double(ControlMeasure::*statFunc)() const,
1125  double min,double max) {
1126 
1127  QList< ControlMeasure * >measures;
1128 
1129  //build a list of all the pointers to the relevant measures
1130  //get the number of object points
1131  int nObjPts = this->GetNumPoints();
1132  for (int i=0;i<nObjPts;i++) { //for each Object point
1133  ControlPoint *point = this->GetPoint(i);
1134  if (point->IsIgnored()) continue; //if the point is ignored then continue
1135 
1136  //get the number of measures
1137  int nObs = point->GetNumMeasures();
1138  for (int j=0;j<nObs;j++) { //for every measure
1139  ControlMeasure *measure = point->GetMeasure(j);
1140  if (measure->IsIgnored()) continue;
1141  double temp = (measure->*statFunc)();
1142  if (temp > min)
1143  if (min <= temp && temp <= max) measures.push_back(measure);
1144  }
1145  }
1146 
1147  //sort the measures
1148  ControlMeasureLessThanFunctor lessThan(statFunc);
1149  qSort(measures.begin(),measures.end(),lessThan);
1150 
1151  return measures;
1152  }
1153 
1154 
1160  void ControlNet::DeleteMeasuresWithId(QString serialNumber) {
1161  ValidateSerialNumber(serialNumber);
1162 
1163  ControlCubeGraphNode *csn = (*cubeGraphNodes)[serialNumber];
1164  QList< ControlMeasure * > measures = csn->getMeasures();
1165  foreach(ControlMeasure * measure, measures) {
1166  measure->Parent()->Delete(measure);
1167  }
1168  }
1169 
1170 
1176  void ControlNet::ComputeResiduals() {
1177  // TODO: Make sure the cameras have been initialized
1178 
1179  QHashIterator< QString, ControlPoint * > i(*points);
1180  while (i.hasNext()) {
1181  i.next();
1182  i.value()->ComputeResiduals();
1183  }
1184  }
1185 
1186 
1192  void ControlNet::ComputeApriori() {
1193  // TODO: Make sure the cameras have been initialized
1194  QHashIterator< QString, ControlPoint * > i(*points);
1195  while (i.hasNext()) {
1196  i.next();
1197  ControlPoint *point = i.value();
1198  if ( !point->IsIgnored() )
1199  point->ComputeApriori();
1200  }
1201  }
1202 
1203 
1210  double ControlNet::AverageResidual() {
1211  // TODO: Make sure the cameras have been initialized
1212  double avgResidual = 0.0;
1213  int count = 0;
1214  QHashIterator< QString, ControlPoint * > i(*points);
1215  while (i.hasNext()) {
1216  i.next();
1217  ControlPoint *point = i.value();
1218  if (!point->IsIgnored()) {
1219  avgResidual += point->GetStatistic(
1220  &ControlMeasure::GetResidualMagnitude).Average();
1221  count++;
1222  }
1223  }
1224 
1225  if (count != 0)
1226  avgResidual /= count;
1227 
1228  return avgResidual;
1229  }
1230 
1231 
1239  Isis::Camera *ControlNet::Camera(int index) {
1240  return p_cameraList[index];
1241  }
1242 
1243 
1251  QString ControlNet::CreatedDate() const {
1252  return p_created;
1253  }
1254 
1255 
1261  QString ControlNet::Description() const {
1262  return p_description;
1263  }
1264 
1265 
1278  ControlPoint *ControlNet::FindClosest(QString serialNumber,
1279  double sample, double line) {
1280  if (!cubeGraphNodes->contains(serialNumber)) {
1281  QString msg = "serialNumber [";
1282  msg += serialNumber;
1283  msg += "] not found in ControlNet";
1284  throw IException(IException::Programmer, msg, _FILEINFO_);
1285  }
1286 
1287  const double SEARCH_DISTANCE = 99999999.0;
1288  double minDist = SEARCH_DISTANCE;
1289  ControlPoint *closestPoint = NULL;
1290 
1291  ControlCubeGraphNode *csn = (*cubeGraphNodes)[serialNumber];
1292  QList< ControlMeasure * > measures = csn->getMeasures();
1293  for (int i = 0; i < measures.size(); i++) {
1294  ControlMeasure *measureToCheck = measures[i];
1295 
1296  //Find closest line sample & return that controlpoint
1297  double dx = fabs(sample - measureToCheck->GetSample());
1298  double dy = fabs(line - measureToCheck->GetLine());
1299 
1300  double dist = sqrt((dx * dx) + (dy * dy));
1301 
1302  if (dist < minDist) {
1303  minDist = dist;
1304  closestPoint = measureToCheck->Parent();
1305  }
1306  }
1307 
1308  if (!closestPoint) {
1309  IString msg = "No point found within ";
1310  msg += IString(SEARCH_DISTANCE);
1311  msg += "pixels of sample/line [";
1312  msg += IString(sample);
1313  msg += ", ";
1314  msg += IString(line);
1315  msg += "]";
1316  throw IException(IException::Programmer, msg, _FILEINFO_);
1317  }
1318 
1319  return closestPoint;
1320  }
1321 
1322 
1324  bool ControlNet::IsValid() const {
1325  return !p_invalid;
1326  }
1327 
1328 
1335  double ControlNet::GetMaximumResidual() {
1336  // TODO: Make sure the cameras have been initialized
1337 
1338  double maxResidual = 0.0;
1339  foreach(ControlPoint * p, *points) {
1340  double residual = p->GetStatistic(
1341  &ControlMeasure::GetResidualMagnitude).Maximum();
1342  if (residual > maxResidual)
1343  maxResidual = residual;
1344  }
1345 
1346  return maxResidual;
1347  }
1348 
1349 
1350  QString ControlNet::GetNetworkId() const {
1351  return p_networkId;
1352  }
1353 
1354 
1361  int ControlNet::GetNumEditLockMeasures() {
1362  int numLockedMeasures = 0;
1363  foreach(ControlPoint * p, *points) {
1364  numLockedMeasures += p->GetNumLockedMeasures();
1365  }
1366 
1367  return numLockedMeasures;
1368  }
1369 
1370 
1376  int ControlNet::GetNumEditLockPoints() {
1377  int editLockPoints = 0;
1378  foreach(ControlPoint * p, *points) {
1379  if (p->IsEditLocked())
1380  editLockPoints++;
1381  }
1382 
1383  return editLockPoints;
1384  }
1385 
1386 
1393  int ControlNet::GetNumIgnoredMeasures() {
1394  int numIgnoredMeasures = 0;
1395  foreach(ControlPoint * p, *points) {
1396  numIgnoredMeasures += p->GetNumMeasures() - p->GetNumValidMeasures();
1397  }
1398 
1399  return numIgnoredMeasures;
1400  }
1401 
1402 
1411  int ControlNet::GetNumberOfValidMeasuresInImage(const QString &serialNumber) {
1412  return p_cameraValidMeasuresMap[serialNumber];
1413  }
1414 
1415 
1421  int ControlNet::GetNumberOfJigsawRejectedMeasuresInImage(const QString &serialNumber) {
1422  return p_cameraRejectedMeasuresMap[serialNumber];
1423  }
1424 
1425 
1431  void ControlNet::ClearJigsawRejected() {
1432  foreach(ControlPoint * p, *points) {
1433  p->ClearJigsawRejected();
1434  }
1435  }
1436 
1437 
1442  void ControlNet::IncrementNumberOfRejectedMeasuresInImage(const QString &serialNumber) {
1443  p_cameraRejectedMeasuresMap[serialNumber]++;
1444  }
1445 
1446 
1451  void ControlNet::DecrementNumberOfRejectedMeasuresInImage(const QString &serialNumber) {
1452  if (p_cameraRejectedMeasuresMap[serialNumber] > 0)
1453  p_cameraRejectedMeasuresMap[serialNumber]--;
1454  }
1455 
1456 
1462  int ControlNet::GetNumMeasures() const {
1463  int numMeasures = 0;
1464  foreach(ControlPoint * p, *points) {
1465  numMeasures += p->GetNumMeasures();
1466  }
1467 
1468  return numMeasures;
1469  }
1470 
1471 
1473  int ControlNet::GetNumPoints() const {
1474  return points->size();
1475  }
1476 
1477 
1487  int ControlNet::GetNumValidMeasures() {
1488  int numValidMeasures = 0;
1489  foreach(ControlPoint * p, *points) {
1490  if (!p->IsIgnored())
1491  numValidMeasures += p->GetNumValidMeasures();
1492  }
1493 
1494  return numValidMeasures;
1495  }
1496 
1497 
1503  int ControlNet::GetNumValidPoints() {
1504  int validPoints = 0;
1505  foreach(ControlPoint * p, *points) {
1506  if (!p->IsIgnored())
1507  validPoints++;
1508  }
1509 
1510  return validPoints;
1511  }
1512 
1513 
1515  QString ControlNet::GetTarget() const {
1516  return p_targetName;
1517  }
1518 
1519 
1521  QString ControlNet::GetUserName() const {
1522  return p_userName;
1523  }
1524 
1525 
1527  QList< ControlPoint * > ControlNet::GetPoints() {
1528  QList< ControlPoint * > orderedPoints;
1529 
1530  for (int i = 0; i < pointIds->size(); i++) {
1531  orderedPoints.append(GetPoint(i));
1532  }
1533 
1534  return orderedPoints;
1535  }
1536 
1537 
1539  QList< QString > ControlNet::GetPointIds() const {
1540  return *pointIds;
1541  }
1542 
1543 
1549  void ControlNet::SetCreatedDate(const QString &date) {
1550  p_created = date;
1551  }
1552 
1553 
1559  void ControlNet::SetDescription(const QString &newDescription) {
1560  p_description = newDescription;
1561  }
1562 
1563 
1569  void ControlNet::SetImages(const QString &imageListFile) {
1570  SerialNumberList list(imageListFile);
1571  SetImages(list);
1572  }
1573 
1574 
1590  void ControlNet::SetImages(SerialNumberList &list, Progress *progress) {
1591  // First check if cameras have already been setup via another SetImages call
1592  if (p_cameraList.size() > 0) {
1593  return;
1594  }
1595  // Prep for reporting progress
1596  if (progress != NULL) {
1597  progress->SetText("Setting input images...");
1598  progress->SetMaximumSteps(list.size());
1599  progress->CheckStatus();
1600  }
1601  // Open the camera for all the images in the serial number list
1602  for (int i = 0; i < list.size(); i++) {
1603  QString serialNumber = list.serialNumber(i);
1604  QString filename = list.fileName(i);
1605  Cube cube(filename, "r");
1606 
1607  try {
1608  Isis::Camera *cam = CameraFactory::Create(cube);
1609  p_cameraMap[serialNumber] = cam;
1610  p_cameraValidMeasuresMap[serialNumber] = 0;
1611  p_cameraRejectedMeasuresMap[serialNumber] = 0;
1612  p_cameraList.push_back(cam);
1613  }
1614  catch (IException &e) {
1615  QString msg = "Unable to create camera for cube file ";
1616  msg += filename;
1617  throw IException(e, IException::Unknown, msg, _FILEINFO_);
1618  }
1619 
1620  if (progress != NULL)
1621  progress->CheckStatus();
1622  }
1623 
1624  // Loop through all measures and set the camera
1625  QHashIterator< QString, ControlPoint * > p(*points);
1626  while (p.hasNext()) {
1627  p.next();
1628  ControlPoint *curPoint = p.value();
1629 
1630  QList< QString > serialNums = curPoint->getCubeSerialNumbers();
1631  for (int m = 0; m < serialNums.size(); m++) {
1632  ControlMeasure *curMeasure = (*curPoint)[serialNums[m]];
1633 
1634  QString serialNumber = curMeasure->GetCubeSerialNumber();
1635  if (list.hasSerialNumber(serialNumber)) {
1636  curMeasure->SetCamera(p_cameraMap[serialNumber]);
1637 
1638  // increment number of measures for this image (camera)
1639  if (!curMeasure->IsIgnored()) p_cameraValidMeasuresMap[serialNumber]++;
1640  }
1641  else {
1642  IString msg = "Control point [" + curPoint->GetId() +
1643  "], measure [" + curMeasure->GetCubeSerialNumber() +
1644  "] does not have a cube with a matching serial number";
1645  throw IException(IException::User, msg, _FILEINFO_);
1646  }
1647  }
1648  }
1649  }
1650 
1651 
1657  void ControlNet::SetModifiedDate(const QString &date) {
1658  p_modified = date;
1659  }
1660 
1661 
1669  void ControlNet::SetMutex(QMutex *mutex) {
1670  m_mutex = mutex;
1671  }
1672 
1673 
1679  void ControlNet::SetNetworkId(const QString &id) {
1680  p_networkId = id;
1681  }
1682 
1683 
1695  void ControlNet::SetTarget(const QString &target) {
1696  QScopedPointer <QMutexLocker> locker;
1697 
1698  if (m_mutex) {
1699  locker.reset(new QMutexLocker(m_mutex));
1700  }
1701 
1702  p_targetName = target;
1703 
1704  p_targetRadii.clear();
1705  try {
1706  PvlGroup pvlRadii = Target::radiiGroup(target);
1707  p_targetRadii.push_back(Distance(pvlRadii["EquatorialRadius"],
1708  Distance::Meters));
1709  // The method Projection::Radii does not provide the B radius
1710  p_targetRadii.push_back(Distance(pvlRadii["EquatorialRadius"],
1711  Distance::Meters));
1712  p_targetRadii.push_back(Distance(pvlRadii["PolarRadius"],
1713  Distance::Meters));
1714  }
1715  catch (IException &e) {
1716  // Fill target radii vector will Null-valued distances
1717  p_targetRadii.push_back(Distance());
1718  p_targetRadii.push_back(Distance());
1719  p_targetRadii.push_back(Distance());
1720  }
1721  }
1722 
1723 
1731  void ControlNet::SetTarget(Pvl label) {
1732  QScopedPointer <QMutexLocker> locker;
1733 
1734  if (m_mutex) {
1735  locker.reset(new QMutexLocker(m_mutex));
1736  }
1737 
1738  PvlGroup mapping;
1739  p_targetRadii.clear();
1740  try {
1741  if ( (label.hasObject("IsisCube") && label.findObject("IsisCube").hasGroup("Mapping"))
1742  || label.hasGroup("Mapping") ) {
1743  mapping = label.findGroup("Mapping", Pvl::Traverse);
1744  }
1745  // If radii values don't exist in the labels
1746  // or if they are set to null,
1747  // try to get target radii using the TargetName or NaifKeywords object values
1748  Distance equatorialRadius, polarRadius;
1749  if (!mapping.hasKeyword("EquatorialRadius")
1750  || !mapping.hasKeyword("PolarRadius")) {
1751 
1752  mapping = Target::radiiGroup(label, mapping);
1753 
1754  }
1755 
1756  equatorialRadius = Distance(mapping["EquatorialRadius"], Distance::Meters);
1757  polarRadius = Distance(mapping["PolarRadius"], Distance::Meters);
1758 
1759  p_targetRadii.push_back(equatorialRadius);
1760  p_targetRadii.push_back(equatorialRadius);
1761  p_targetRadii.push_back(polarRadius);
1762  }
1763  catch (IException &e) {
1764  // leave equatorialRadius and polarRadius as Null-valued distances if this fails
1765  p_targetRadii.push_back(Distance());
1766  p_targetRadii.push_back(Distance());
1767  p_targetRadii.push_back(Distance());
1768  }
1769 
1770  if (mapping.hasKeyword("TargetName")) {
1771  p_targetName = mapping["TargetName"][0];
1772  }
1773  else {
1774  p_targetName = "";
1775  }
1776  }
1777 
1778 
1790  void ControlNet::SetTarget(const QString &target,
1791  const QVector<Distance> &radii) {
1792  QScopedPointer <QMutexLocker> locker;
1793 
1794  if (m_mutex) {
1795  locker.reset(new QMutexLocker(m_mutex));
1796  }
1797 
1798  if (radii.size() != 3) {
1799  throw IException(IException::Unknown,
1800  "Unable to set target radii. The given list must have length 3.",
1801  _FILEINFO_);
1802  }
1803 
1804  p_targetName = target;
1805  p_targetRadii = radii.toStdVector();
1806 
1807  }
1808 
1809 
1815  void ControlNet::SetUserName(const QString &name) {
1816  p_userName = name;
1817  }
1818 
1819 
1834  void ControlNet::swap(ControlNet &other) {
1835  std::swap(points, other.points);
1836  std::swap(cubeGraphNodes, other.cubeGraphNodes);
1837  std::swap(pointIds, other.pointIds);
1838  std::swap(m_mutex, other.m_mutex);
1839  std::swap(p_targetName, other.p_targetName);
1840  std::swap(p_networkId, other.p_networkId);
1841  std::swap(p_created, other.p_created);
1842  std::swap(p_modified, other.p_modified);
1843  std::swap(p_description, other.p_description);
1844  std::swap(p_userName, other.p_userName);
1845  std::swap(p_cameraMap, other.p_cameraMap);
1846  std::swap(p_cameraValidMeasuresMap, other.p_cameraValidMeasuresMap);
1847  std::swap(p_cameraRejectedMeasuresMap, other.p_cameraRejectedMeasuresMap);
1848  std::swap(p_cameraList, other.p_cameraList);
1849  std::swap(p_targetRadii, other.p_targetRadii);
1850  std::swap(p_invalid, other.p_invalid);
1851 
1852  // points have parent pointers that need updated too...
1853  QHashIterator< QString, ControlPoint * > i(*points);
1854  while (i.hasNext()) {
1855  i.next().value()->parentNetwork = this;
1856  }
1857 
1858  QHashIterator< QString, ControlPoint * > i2(*other.points);
1859  while (i2.hasNext()) {
1860  i2.next().value()->parentNetwork = &other;
1861  }
1862  }
1863 
1864 
1872  ControlNet &ControlNet::operator=(const ControlNet &other) {
1873  // Optimization: if this == other do nothing.
1874  if (this != &other) {
1875  // copy & swap
1876  ControlNet copy(other);
1877  swap(copy);
1878  }
1879 
1880  return *this;
1881  }
1882 
1883 
1884  const ControlPoint *ControlNet::GetPoint(QString id) const {
1885  if (!points->contains(id)) {
1886  IString msg = "The control network has no control points with an ID "
1887  "equal to [" + id + "]";
1888  throw IException(IException::Programmer, msg, _FILEINFO_);
1889  }
1890 
1891  return points->value(id);
1892  }
1893 
1894 
1895  ControlPoint *ControlNet::GetPoint(QString id) {
1896  if (!points->contains(id)) {
1897  IString msg = "The control network has no control points with an ID "
1898  "equal to [" + id + "]";
1899  throw IException(IException::Programmer, msg, _FILEINFO_);
1900  }
1901 
1902  return (*points)[id];
1903  }
1904 
1905 
1906  const ControlPoint *ControlNet::GetPoint(int index) const {
1907  if (index < 0 || index >= pointIds->size()) {
1908  IString msg = "Index [" + IString(index) + "] out of range";
1909  throw IException(IException::Programmer, msg, _FILEINFO_);
1910  }
1911 
1912  return GetPoint(pointIds->at(index));
1913  }
1914 
1915 
1916  ControlPoint *ControlNet::GetPoint(int index) {
1917  if (index < 0 || index >= pointIds->size()) {
1918  IString msg = "Index [" + IString(index) + "] out of range";
1919  throw IException(IException::Programmer, msg, _FILEINFO_);
1920  }
1921 
1922  return GetPoint(pointIds->at(index));
1923  }
1924 
1925 
1926  const ControlCubeGraphNode *ControlNet::getGraphNode(
1927  QString serialNumber) const {
1928  if (!cubeGraphNodes->contains(serialNumber)) {
1929  IString msg = "Serial Number [" + serialNumber + "] does not exist in"
1930  " the network.";
1931  throw IException(IException::Programmer, msg, _FILEINFO_);
1932  }
1933 
1934  return cubeGraphNodes->value(serialNumber);
1935  }
1936 
1937  ControlCubeGraphNode *ControlNet::getGraphNode(
1938  QString serialNumber) {
1939  if (!cubeGraphNodes->contains(serialNumber)) {
1940  IString msg = "Serial Number [" + serialNumber + "] does not exist in"
1941  " the network.";
1942  throw IException(IException::Programmer, msg, _FILEINFO_);
1943  }
1944 
1945  return cubeGraphNodes->value(serialNumber);
1946  }
1947 
1948 
1954  std::vector<Distance> ControlNet::GetTargetRadii() {
1955  return p_targetRadii;
1956  }
1957 
1958 
1959  const ControlPoint *ControlNet::operator[](QString id) const {
1960  return GetPoint(id);
1961  }
1962 
1963 
1964  ControlPoint *ControlNet::operator[](QString id) {
1965  return GetPoint(id);
1966  }
1967 
1968 
1969  const ControlPoint *ControlNet::operator[](int index) const {
1970  return GetPoint(index);
1971  }
1972 
1973 
1974  ControlPoint *ControlNet::operator[](int index) {
1975  return GetPoint(index);
1976  }
1977 }
bool p_invalid
If the Control Network is currently invalid.
Definition: ControlNet.h:441
Definition: Process.h:32
Serial Number with added functionality for Control Networks.
Encapsulation of a vertex in a minimum spanning tree.
Definition: ControlNet.h:363
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:101
QString p_targetName
Name of the target.
Definition: ControlNet.h:428
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
Status ComputeApriori()
This method computes the apriori lat/lon for a point.
Statistics GetStatistic(double(ControlMeasure::*statFunc)() const) const
This function will call a given method on every control measure that this point has.
int size() const
How many serial number / filename combos are in the list.
std::vector< Distance > p_targetRadii
Radii of target body.
Definition: ControlNet.h:439
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
void ClearJigsawRejected()
Set jigsaw rejected flag for all measures to false and set the jigsaw rejected flag for the point its...
QString p_description
Textual Description of network.
Definition: ControlNet.h:432
QString serialNumber(const QString &filename)
Return a serial number given a filename.
ControlPoint * getPoint()
Get the point representation of this vertex.
Definition: ControlNet.h:400
std::vector< Isis::Camera * > p_cameraList
Vector of image number to camera.
Definition: ControlNet.h:438
int GetNumValidMeasures() const
QString p_networkId
The Network Id.
Definition: ControlNet.h:429
ControlNet * parentNetwork
List of Control Measures.
Definition: ControlPoint.h:574
ControlNetFileHeaderV0002 & GetNetworkHeader()
Get the control network level information - things like NetworkID, TargetName, etc...
int GetNumPoints() const
Return the number of control points in the network.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance measurement, usually in meters.
Definition: Distance.h:47
QString p_created
Creation Date.
Definition: ControlNet.h:430
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:121
QString fileName(const QString &sn)
Return a filename given a serial number.
QList< ControlPointFileEntryV0002 > & GetNetworkPoints()
Get the control point data along with the log data.
Program progress reporter.
Definition: Progress.h:58
QString p_userName
The user who created the network.
Definition: ControlNet.h:433
a control network
Definition: ControlNet.h:207
QString GetId() const
Return the Id of the control point.
Status SetCamera(Isis::Camera *camera)
Set pointer to camera associated with a measure.
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition: Progress.cpp:77
std::map< QString, int > p_cameraValidMeasuresMap
A map from serialnumber to #measures.
Definition: ControlNet.h:435
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
double Average() const
Computes and returns the average.
Definition: Statistics.cpp:317
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
void addMeasure(ControlMeasure *measure)
Adds a measure.
double Maximum() const
Returns the absolute maximum double found in all data passed through the AddData method.
Definition: Statistics.cpp:420
std::map< QString, int > p_cameraRejectedMeasuresMap
A map from serialnumber to #rejected measures ...
Definition: ControlNet.h:436
A single control point.
Definition: ControlPoint.h:339
ControlVertex * getRoot()
Get the root node, or greatest ancestor.
Definition: ControlNet.h:386
Container for cube-like labels.
Definition: Pvl.h:135
QHash< QString, ControlPoint * > * points
hash ControlPoints by ControlPoint Id
Definition: ControlNet.h:421
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not...
Definition: PvlObject.h:335
QList< ControlMeasure * > getMeasures(bool excludeIgnored=false) const
Isis exception class.
Definition: IException.h:99
Adds specific functionality to C++ strings.
Definition: IString.h:179
a control measurement
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
Handle Binary Control Network Files version 2.
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:222
int GetNumLockedMeasures() const
Returns the number of locked control measures.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
QString p_modified
Date Last Modified.
Definition: ControlNet.h:431
Serial Number list generator.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube&#39;s serial number.
QList< QString > getCubeSerialNumbers() const
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
void clear()
Clears PvlKeywords.
Definition: PvlContainer.h:106
std::map< QString, Isis::Camera * > p_cameraMap
A map from serialnumber to camera.
Definition: ControlNet.h:434
QHash< QString, ControlCubeGraphNode * > * cubeGraphNodes
hash ControlCubeGraphNodes by CubeSerialNumber
Definition: ControlNet.h:424
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:16:25