Loading isis/src/control/objs/ControlNet/ControlNet.cpp +92 −102 Original line number Diff line number Diff line Loading @@ -6,12 +6,10 @@ #include <cmath> #include <sstream> #include <QtAlgorithms> #include <QDebug> #include <QMutex> #include <QMutexLocker> #include <QPair> #include <QQueue> #include <QScopedPointer> #include <QSet> #include <QTime> Loading @@ -25,7 +23,6 @@ #include "ControlMeasure.h" #include "ControlNetVersioner.h" #include "ControlPoint.h" #include "ControlCubeGraphNode.h" #include "Distance.h" #include "FileName.h" #include "IException.h" Loading Loading @@ -336,15 +333,15 @@ namespace Isis { /** * Adds a whole point to the control net graph. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::pointAdded!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::pointAdded!" * @throws IException::Programmer "ControlNet does not contain the point." */ void ControlNet::pointAdded(ControlPoint *point) { if (!point) { IString msg = "NULL point passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::pointAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -354,25 +351,25 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure // Make sure there is a node for every measure for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); // if the graph doesn't have the sn // If the graph doesn't have the sn, add a node for it if (!m_vertexMap.contains(sn)) { ImageVertex newVertex = boost::add_vertex(m_controlGraph); m_controlGraph[newVertex].serial = sn; Image newImage; newImage.serial = sn; ImageVertex newVertex = boost::add_vertex(newImage, m_controlGraph); m_vertexMap.insert(sn, newVertex); } } foreach(ControlMeasure* measure, point->getMeasures()) { // add the measure to the corresponding node // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; // in this measure's node add connections to the other nodes reachable from // In this measure's node add connections to the other nodes reachable from // its point if (!point->IsIgnored() && !measure->IsIgnored()) { for (int i = 0; i < point->GetNumMeasures(); i++) { Loading @@ -380,6 +377,9 @@ namespace Isis { if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -390,8 +390,12 @@ namespace Isis { } } // temporarily print graph to test // This doesn't even return a string right now, just couts. /** * Used for verifying graph intergrity * * @returns A string representation of the ControlNet graph */ QString ControlNet::GraphToString() const { // Iterate through the vertices and print them out Loading Loading @@ -420,29 +424,29 @@ namespace Isis { /** * Updates the ControlCubeGraphNode for the measure's serial number to * reflect the addition. If there is currently no ControlCubeGraphNode for * this measure's serial, then a new ControlCubeGraphNode is created with * Updates the ControlNet graph for the measure's serial number to * reflect the addition. If there is currently no node for * this measure's serial, then a new node is created with * this measure as its first. * * @param measure The measure added to the network. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::measureAdded!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::measureAdded!" * @throws IException::Programmer "ControlNet does not contain the point." */ void ControlNet::measureAdded(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -452,21 +456,21 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure in this measure's parent // Make sure there is a node for every measure in this measure's parent for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); // if the graph doesn't have the sn (boost) // If the graph doesn't have the sn, add the node. if (!m_vertexMap.contains(sn)) { ImageVertex newVertex = boost::add_vertex(m_controlGraph); m_controlGraph[newVertex].serial = sn; Image newImage; newImage.serial = sn; ImageVertex newVertex = boost::add_vertex(newImage, m_controlGraph); m_vertexMap.insert(sn, newVertex); } } // add the measure to the corresponding node // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; // in this measure's node add connections to the other nodes reachable from Loading @@ -477,6 +481,9 @@ namespace Isis { if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -488,28 +495,28 @@ namespace Isis { /** * Updates the connections for the ControlCubeGraphNode associated with the * Updates the connections for the ControlNet graph associated with the * measure's serial number to reflect the unignoration. * * @param measure The measure unignored from the network. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::measureUnIgnored!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::measureUnIgnored!" * @throws IException::Programmer "ControlNet does not contain the point." * @throws IException::Programmer "Node does not exist for the cube serial number." */ void ControlNet::measureUnIgnored(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureUnIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureUnIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -519,7 +526,7 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure in this measure's parent // Make sure there is a node for every measure in this measure's parent for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); if (!m_vertexMap.contains(sn)) { Loading @@ -532,13 +539,16 @@ namespace Isis { if (!point->IsIgnored()) { QString serial = measure->GetCubeSerialNumber(); // in this measure's node add connections to the other nodes reachable // In this measure's node add connections to the other nodes reachable // from its point for (int i = 0; i < point->GetNumMeasures(); i++) { ControlMeasure *cm = point->GetMeasure(i); if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -565,9 +575,9 @@ namespace Isis { /** * Updates the ControlCubeGraphNode for this measure's serial number to * Updates the node for this measure's serial number to * reflect the deletion. If this is the only measure left in the containing * ControlCubeGraphNode, then the ControlCubeGraphNode is deleted as well. * node, then the node is deleted as well. * * @param measure The measure removed from the network. */ Loading @@ -576,16 +586,18 @@ namespace Isis { QString serial = measure->GetCubeSerialNumber(); ASSERT(m_vertexGraph->contains(serial)); // remove connections to and from this node // Remove connections to and from this node if (!measure->IsIgnored() && !measure->Parent()->IsIgnored()) { // Break connections measureIgnored(measure); } // Remove the measure from the associated node. // Conceptually, I think this belongs in measureIgnored, but it isn't done // for the old graph. m_controlGraph[m_vertexMap[serial]].measures.remove(measure->Parent()); // Decrement the edge strength & remove edge if -> 0 happens in measureIgnored // If this caused the node to be empty, then delete the node. if (m_controlGraph[m_vertexMap[serial]].measures.size() <= 0) { boost::clear_vertex(m_vertexMap[serial], m_controlGraph); Loading @@ -595,36 +607,46 @@ namespace Isis { } /** * Updates the edges in the ControlNet graph to reflect the ignored * measure. If this was the last measure connecting one node to another, * then the edge is deleted as well. * * @param measure The measure set to ignored from the network. */ void ControlNet::measureIgnored(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } QString serial = measure->GetCubeSerialNumber(); if (!m_vertexMap.contains(serial)) { if (!ValidateSerialNumber(serial)) { QString msg = "Node does not exist for ["; msg += serial + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } // remove connections to and from this node // Decrement the edge strength for edges from this node // Remove edge if the strength becomes 0. for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); if (m_vertexMap.contains(sn)) { if (QString::compare(serial, sn) !=0) { // std::cout << point->GetId() << ":" << serial << " --- " << sn << std::endl; // This is necessary because boost doesn't add separate edges for A -> B and // B -> A like we used to. // We need to check if the edge still exists. // boost doesn't add separate edges for A -> B and B -> A like the old graph. // result.first is the ImageConnection, if found // result.second is true if the edge exists; otherwise false. std::pair<ImageConnection, bool> result = boost::edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph); Loading Loading @@ -746,6 +768,7 @@ namespace Isis { VertexIndexMap indexMap; VertexIndexMapAdaptor indexMapAdaptor(indexMap); // Needed to use connected_componenets QList< QString> serials = m_vertexMap.keys(); for (int i = 0; i < serials.size(); i++) { boost::put(indexMapAdaptor, m_vertexMap[serials[i]], i); Loading @@ -753,42 +776,25 @@ namespace Isis { VertexIndexMap componentMap; VertexIndexMapAdaptor componentAdaptor(componentMap); size_t numComponents = boost::connected_components(m_controlGraph, componentAdaptor, boost::connected_components(m_controlGraph, componentAdaptor, boost::vertex_index_map(indexMapAdaptor)); // std::cout << "Number of components:" << std::endl; // std::cout << numComponents << std::endl; // std::cout << "Size of return: " << componentMap.size() << std::endl; // This is not efficient, but works QHash<int, QList<QString> > islandsByGroup; std::map<ImageVertex, size_t>::iterator it = componentMap.begin(); while(it != componentMap.end()) { ImageVertex vertex = it->first; QString serial = m_controlGraph[vertex].serial; QString serial = m_controlGraph[it->first].serial; int group = (int) it->second; // std::cout << group << " :: " << serial << std::endl; islandsByGroup[group].append(serial); ++it; if (group > islandStrings.size() - 1) { QList<QString> tempList; tempList.append(serial); islandStrings.append(tempList); } // std::cout << std::endl; QList<int> groups = islandsByGroup.keys(); for (int i=0; i<groups.size(); i++) { std::cout << "Group: " << groups[i] << std::endl; QList<QString> temp = islandsByGroup[groups[i]]; islandStrings.append(temp); // <--- this converts to the output format; for (int j=0; j<temp.size();j++) { std::cout << " ----- " << temp[j] << std::endl; else { islandStrings[group].append(serial); } ++it; } return islandStrings; } Loading @@ -797,9 +803,7 @@ namespace Isis { * @returns The total number of edges in the bi-directional graph for images */ int ControlNet::getEdgeCount() const { int total = boost::num_edges(m_controlGraph); return total; return boost::num_edges(m_controlGraph); } Loading @@ -823,11 +827,7 @@ namespace Isis { * @param serialNumber the cube serial number to validate */ bool ControlNet::ValidateSerialNumber(QString serialNumber) const { if (!m_vertexMap.contains(serialNumber)) { return false; } return true; return m_vertexMap.contains(serialNumber); } Loading @@ -837,14 +837,13 @@ namespace Isis { * @returns A list of all measures which are in a given cube */ QList< ControlMeasure * > ControlNet::GetMeasuresInCube(QString serialNumber) { if( ValidateSerialNumber(serialNumber) ) { return m_controlGraph[m_vertexMap[serialNumber]].measures.values(); } else { if( !ValidateSerialNumber(serialNumber) ) { IString msg = "Cube Serial Number [" + serialNumber + "] not found in " "the network"; throw IException(IException::Programmer, msg, _FILEINFO_); } return m_controlGraph[m_vertexMap[serialNumber]].measures.values(); } Loading Loading @@ -917,7 +916,7 @@ namespace Isis { ControlPoint *point = this->GetPoint(i); if (point->IsIgnored()) continue; //if the point is ignored then continue //get the number of measures // Get the number of measures int nObs = point->GetNumMeasures(); for (int j=0;j<nObs;j++) { //for every measure ControlMeasure *measure = point->GetMeasure(j); Loading @@ -928,7 +927,7 @@ namespace Isis { } } //sort the measures // Sort the measures ControlMeasureLessThanFunctor lessThan(statFunc); qSort(measures.begin(),measures.end(),lessThan); Loading Loading @@ -1045,12 +1044,6 @@ namespace Isis { */ ControlPoint *ControlNet::FindClosest(QString serialNumber, double sample, double line) { // if (!cubeGraphNodes->contains(serialNumber)) { // QString msg = "serialNumber ["; // msg += serialNumber; // msg += "] not found in ControlNet"; // throw IException(IException::Programmer, msg, _FILEINFO_); // } if (!ValidateSerialNumber(serialNumber)) { QString msg = "serialNumber ["; Loading @@ -1063,9 +1056,6 @@ namespace Isis { double minDist = SEARCH_DISTANCE; ControlPoint *closestPoint = NULL; // ControlCubeGraphNode *csn = (*cubeGraphNodes)[serialNumber]; // QList< ControlMeasure * > measures = csn->getMeasures(); QList < ControlMeasure * > measures = m_controlGraph[m_vertexMap[serialNumber]].measures.values(); for (int i = 0; i < measures.size(); i++) { Loading isis/src/control/objs/ControlNet/ControlNet.h +2 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <boost/graph/adjacency_list.hpp> #include <boost/graph/connected_components.hpp> template< typename A, typename B > class QHash; template< typename T > class QList; template< typename A, typename B > struct QPair; Loading @@ -45,7 +44,6 @@ template< typename T > class QSet; class QMutex; class QString; namespace Isis { class Camera; class ControlMeasure; Loading Loading @@ -369,6 +367,8 @@ namespace Isis { //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; //! hash ControlCubeGraphNodes by CubeSerialNumber // structs and typedefs for the boost graph struct Image { QString serial; Loading @@ -385,10 +385,8 @@ namespace Isis { typedef std::map<ImageVertex, size_t> VertexIndexMap; typedef boost::associative_property_map<VertexIndexMap> VertexIndexMapAdaptor; typedef Network::out_edge_iterator ConnectionIterator; QHash<QString, ImageVertex> m_vertexMap; //!< The SN -> vertex hash for the boost graph Network m_controlGraph; //!< The boost graph QStringList *pointIds; QMutex *m_mutex; Loading Loading
isis/src/control/objs/ControlNet/ControlNet.cpp +92 −102 Original line number Diff line number Diff line Loading @@ -6,12 +6,10 @@ #include <cmath> #include <sstream> #include <QtAlgorithms> #include <QDebug> #include <QMutex> #include <QMutexLocker> #include <QPair> #include <QQueue> #include <QScopedPointer> #include <QSet> #include <QTime> Loading @@ -25,7 +23,6 @@ #include "ControlMeasure.h" #include "ControlNetVersioner.h" #include "ControlPoint.h" #include "ControlCubeGraphNode.h" #include "Distance.h" #include "FileName.h" #include "IException.h" Loading Loading @@ -336,15 +333,15 @@ namespace Isis { /** * Adds a whole point to the control net graph. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::pointAdded!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::pointAdded!" * @throws IException::Programmer "ControlNet does not contain the point." */ void ControlNet::pointAdded(ControlPoint *point) { if (!point) { IString msg = "NULL point passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::pointAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -354,25 +351,25 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure // Make sure there is a node for every measure for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); // if the graph doesn't have the sn // If the graph doesn't have the sn, add a node for it if (!m_vertexMap.contains(sn)) { ImageVertex newVertex = boost::add_vertex(m_controlGraph); m_controlGraph[newVertex].serial = sn; Image newImage; newImage.serial = sn; ImageVertex newVertex = boost::add_vertex(newImage, m_controlGraph); m_vertexMap.insert(sn, newVertex); } } foreach(ControlMeasure* measure, point->getMeasures()) { // add the measure to the corresponding node // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; // in this measure's node add connections to the other nodes reachable from // In this measure's node add connections to the other nodes reachable from // its point if (!point->IsIgnored() && !measure->IsIgnored()) { for (int i = 0; i < point->GetNumMeasures(); i++) { Loading @@ -380,6 +377,9 @@ namespace Isis { if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -390,8 +390,12 @@ namespace Isis { } } // temporarily print graph to test // This doesn't even return a string right now, just couts. /** * Used for verifying graph intergrity * * @returns A string representation of the ControlNet graph */ QString ControlNet::GraphToString() const { // Iterate through the vertices and print them out Loading Loading @@ -420,29 +424,29 @@ namespace Isis { /** * Updates the ControlCubeGraphNode for the measure's serial number to * reflect the addition. If there is currently no ControlCubeGraphNode for * this measure's serial, then a new ControlCubeGraphNode is created with * Updates the ControlNet graph for the measure's serial number to * reflect the addition. If there is currently no node for * this measure's serial, then a new node is created with * this measure as its first. * * @param measure The measure added to the network. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::measureAdded!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::measureAdded!" * @throws IException::Programmer "ControlNet does not contain the point." */ void ControlNet::measureAdded(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureAdded!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -452,21 +456,21 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure in this measure's parent // Make sure there is a node for every measure in this measure's parent for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); // if the graph doesn't have the sn (boost) // If the graph doesn't have the sn, add the node. if (!m_vertexMap.contains(sn)) { ImageVertex newVertex = boost::add_vertex(m_controlGraph); m_controlGraph[newVertex].serial = sn; Image newImage; newImage.serial = sn; ImageVertex newVertex = boost::add_vertex(newImage, m_controlGraph); m_vertexMap.insert(sn, newVertex); } } // add the measure to the corresponding node // Add the measure to the corresponding node QString serial = measure->GetCubeSerialNumber(); m_controlGraph[m_vertexMap[serial]].measures[measure->Parent()] = measure; // in this measure's node add connections to the other nodes reachable from Loading @@ -477,6 +481,9 @@ namespace Isis { if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -488,28 +495,28 @@ namespace Isis { /** * Updates the connections for the ControlCubeGraphNode associated with the * Updates the connections for the ControlNet graph associated with the * measure's serial number to reflect the unignoration. * * @param measure The measure unignored from the network. * * @throws IException::Programmer "NULL measure passed to ControlNet::AddControlCubeGraphNode!" * @throws IException::Programmer "NULL measure passed to ControlNet::measureUnIgnored!" * @throws IException::Programmer "Control measure with NULL parent passed to * ControlNet::AddControlCubeGraphNode!" * ControlNet::measureUnIgnored!" * @throws IException::Programmer "ControlNet does not contain the point." * @throws IException::Programmer "Node does not exist for the cube serial number." */ void ControlNet::measureUnIgnored(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureUnIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureUnIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } Loading @@ -519,7 +526,7 @@ namespace Isis { throw IException(IException::Programmer, msg, _FILEINFO_); } // make sure there is a node for every measure in this measure's parent // Make sure there is a node for every measure in this measure's parent for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); if (!m_vertexMap.contains(sn)) { Loading @@ -532,13 +539,16 @@ namespace Isis { if (!point->IsIgnored()) { QString serial = measure->GetCubeSerialNumber(); // in this measure's node add connections to the other nodes reachable // In this measure's node add connections to the other nodes reachable // from its point for (int i = 0; i < point->GetNumMeasures(); i++) { ControlMeasure *cm = point->GetMeasure(i); if (!cm->IsIgnored()) { QString sn = cm->GetCubeSerialNumber(); // If the edge doesn't already exist, this adds and returns the edge. // If the edge already exists, this just returns it. (The use of a set // forces the edges to be unique.) ImageConnection connection = boost::add_edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph).first; Loading @@ -565,9 +575,9 @@ namespace Isis { /** * Updates the ControlCubeGraphNode for this measure's serial number to * Updates the node for this measure's serial number to * reflect the deletion. If this is the only measure left in the containing * ControlCubeGraphNode, then the ControlCubeGraphNode is deleted as well. * node, then the node is deleted as well. * * @param measure The measure removed from the network. */ Loading @@ -576,16 +586,18 @@ namespace Isis { QString serial = measure->GetCubeSerialNumber(); ASSERT(m_vertexGraph->contains(serial)); // remove connections to and from this node // Remove connections to and from this node if (!measure->IsIgnored() && !measure->Parent()->IsIgnored()) { // Break connections measureIgnored(measure); } // Remove the measure from the associated node. // Conceptually, I think this belongs in measureIgnored, but it isn't done // for the old graph. m_controlGraph[m_vertexMap[serial]].measures.remove(measure->Parent()); // Decrement the edge strength & remove edge if -> 0 happens in measureIgnored // If this caused the node to be empty, then delete the node. if (m_controlGraph[m_vertexMap[serial]].measures.size() <= 0) { boost::clear_vertex(m_vertexMap[serial], m_controlGraph); Loading @@ -595,36 +607,46 @@ namespace Isis { } /** * Updates the edges in the ControlNet graph to reflect the ignored * measure. If this was the last measure connecting one node to another, * then the edge is deleted as well. * * @param measure The measure set to ignored from the network. */ void ControlNet::measureIgnored(ControlMeasure *measure) { if (!measure) { IString msg = "NULL measure passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } ControlPoint *point = measure->Parent(); if (!point) { IString msg = "Control measure with NULL parent passed to " "ControlNet::AddControlCubeGraphNode!"; "ControlNet::measureIgnored!"; throw IException(IException::Programmer, msg, _FILEINFO_); } QString serial = measure->GetCubeSerialNumber(); if (!m_vertexMap.contains(serial)) { if (!ValidateSerialNumber(serial)) { QString msg = "Node does not exist for ["; msg += serial + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } // remove connections to and from this node // Decrement the edge strength for edges from this node // Remove edge if the strength becomes 0. for (int i = 0; i < point->GetNumMeasures(); i++) { QString sn = point->GetMeasure(i)->GetCubeSerialNumber(); if (m_vertexMap.contains(sn)) { if (QString::compare(serial, sn) !=0) { // std::cout << point->GetId() << ":" << serial << " --- " << sn << std::endl; // This is necessary because boost doesn't add separate edges for A -> B and // B -> A like we used to. // We need to check if the edge still exists. // boost doesn't add separate edges for A -> B and B -> A like the old graph. // result.first is the ImageConnection, if found // result.second is true if the edge exists; otherwise false. std::pair<ImageConnection, bool> result = boost::edge(m_vertexMap[serial], m_vertexMap[sn], m_controlGraph); Loading Loading @@ -746,6 +768,7 @@ namespace Isis { VertexIndexMap indexMap; VertexIndexMapAdaptor indexMapAdaptor(indexMap); // Needed to use connected_componenets QList< QString> serials = m_vertexMap.keys(); for (int i = 0; i < serials.size(); i++) { boost::put(indexMapAdaptor, m_vertexMap[serials[i]], i); Loading @@ -753,42 +776,25 @@ namespace Isis { VertexIndexMap componentMap; VertexIndexMapAdaptor componentAdaptor(componentMap); size_t numComponents = boost::connected_components(m_controlGraph, componentAdaptor, boost::connected_components(m_controlGraph, componentAdaptor, boost::vertex_index_map(indexMapAdaptor)); // std::cout << "Number of components:" << std::endl; // std::cout << numComponents << std::endl; // std::cout << "Size of return: " << componentMap.size() << std::endl; // This is not efficient, but works QHash<int, QList<QString> > islandsByGroup; std::map<ImageVertex, size_t>::iterator it = componentMap.begin(); while(it != componentMap.end()) { ImageVertex vertex = it->first; QString serial = m_controlGraph[vertex].serial; QString serial = m_controlGraph[it->first].serial; int group = (int) it->second; // std::cout << group << " :: " << serial << std::endl; islandsByGroup[group].append(serial); ++it; if (group > islandStrings.size() - 1) { QList<QString> tempList; tempList.append(serial); islandStrings.append(tempList); } // std::cout << std::endl; QList<int> groups = islandsByGroup.keys(); for (int i=0; i<groups.size(); i++) { std::cout << "Group: " << groups[i] << std::endl; QList<QString> temp = islandsByGroup[groups[i]]; islandStrings.append(temp); // <--- this converts to the output format; for (int j=0; j<temp.size();j++) { std::cout << " ----- " << temp[j] << std::endl; else { islandStrings[group].append(serial); } ++it; } return islandStrings; } Loading @@ -797,9 +803,7 @@ namespace Isis { * @returns The total number of edges in the bi-directional graph for images */ int ControlNet::getEdgeCount() const { int total = boost::num_edges(m_controlGraph); return total; return boost::num_edges(m_controlGraph); } Loading @@ -823,11 +827,7 @@ namespace Isis { * @param serialNumber the cube serial number to validate */ bool ControlNet::ValidateSerialNumber(QString serialNumber) const { if (!m_vertexMap.contains(serialNumber)) { return false; } return true; return m_vertexMap.contains(serialNumber); } Loading @@ -837,14 +837,13 @@ namespace Isis { * @returns A list of all measures which are in a given cube */ QList< ControlMeasure * > ControlNet::GetMeasuresInCube(QString serialNumber) { if( ValidateSerialNumber(serialNumber) ) { return m_controlGraph[m_vertexMap[serialNumber]].measures.values(); } else { if( !ValidateSerialNumber(serialNumber) ) { IString msg = "Cube Serial Number [" + serialNumber + "] not found in " "the network"; throw IException(IException::Programmer, msg, _FILEINFO_); } return m_controlGraph[m_vertexMap[serialNumber]].measures.values(); } Loading Loading @@ -917,7 +916,7 @@ namespace Isis { ControlPoint *point = this->GetPoint(i); if (point->IsIgnored()) continue; //if the point is ignored then continue //get the number of measures // Get the number of measures int nObs = point->GetNumMeasures(); for (int j=0;j<nObs;j++) { //for every measure ControlMeasure *measure = point->GetMeasure(j); Loading @@ -928,7 +927,7 @@ namespace Isis { } } //sort the measures // Sort the measures ControlMeasureLessThanFunctor lessThan(statFunc); qSort(measures.begin(),measures.end(),lessThan); Loading Loading @@ -1045,12 +1044,6 @@ namespace Isis { */ ControlPoint *ControlNet::FindClosest(QString serialNumber, double sample, double line) { // if (!cubeGraphNodes->contains(serialNumber)) { // QString msg = "serialNumber ["; // msg += serialNumber; // msg += "] not found in ControlNet"; // throw IException(IException::Programmer, msg, _FILEINFO_); // } if (!ValidateSerialNumber(serialNumber)) { QString msg = "serialNumber ["; Loading @@ -1063,9 +1056,6 @@ namespace Isis { double minDist = SEARCH_DISTANCE; ControlPoint *closestPoint = NULL; // ControlCubeGraphNode *csn = (*cubeGraphNodes)[serialNumber]; // QList< ControlMeasure * > measures = csn->getMeasures(); QList < ControlMeasure * > measures = m_controlGraph[m_vertexMap[serialNumber]].measures.values(); for (int i = 0; i < measures.size(); i++) { Loading
isis/src/control/objs/ControlNet/ControlNet.h +2 −4 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <boost/graph/adjacency_list.hpp> #include <boost/graph/connected_components.hpp> template< typename A, typename B > class QHash; template< typename T > class QList; template< typename A, typename B > struct QPair; Loading @@ -45,7 +44,6 @@ template< typename T > class QSet; class QMutex; class QString; namespace Isis { class Camera; class ControlMeasure; Loading Loading @@ -369,6 +367,8 @@ namespace Isis { //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; //! hash ControlCubeGraphNodes by CubeSerialNumber // structs and typedefs for the boost graph struct Image { QString serial; Loading @@ -385,10 +385,8 @@ namespace Isis { typedef std::map<ImageVertex, size_t> VertexIndexMap; typedef boost::associative_property_map<VertexIndexMap> VertexIndexMapAdaptor; typedef Network::out_edge_iterator ConnectionIterator; QHash<QString, ImageVertex> m_vertexMap; //!< The SN -> vertex hash for the boost graph Network m_controlGraph; //!< The boost graph QStringList *pointIds; QMutex *m_mutex; Loading