Loading autocnet/control/control.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from time import gmtime, strftime import pandas as pd POINT_TYPE = 2 MEASURE_TYPE = 2 class CSeries(pd.Series): """ Loading autocnet/examples/Apollo15/two_image_adjacency.json 0 → 100644 +2 −0 Original line number Diff line number Diff line {"AS15-M-0297_SML.png": ["AS15-M-0298_SML.png"], "AS15-M-0298_SML.png": ["AS15-M-0297_SML.png"]} autocnet/fileio/io_controlnetwork.py +11 −5 Original line number Diff line number Diff line Loading @@ -144,18 +144,24 @@ class IsisStore(object): # Get the subset of the dataframe point = cnet.loc[point_id] try: point_spec.id = point_id except: point_spec.id = str(point_id) point_spec.type = FREEPOINT # Hard coded to free # A single extend call is cheaper than many add calls to pack points measure_iterable = [] for m in point.iterrows(): for name, measure in point.iterrows(): measure_spec = point_spec.Measure() serialnumber = m[0][1] mtype = m[0][2] measure_spec.serialnumber = serialnumber serial_number = name[1] mtype = name[2] measure_spec.serialnumber = serial_number measure_spec.type = mtype measure_spec.sample = measure.x measure_spec.line = measure.y measure_iterable.append(measure_spec) point_spec.measures.extend(measure_iterable) Loading autocnet/fileio/tests/test_io_controlnetwork.py +8 −8 Original line number Diff line number Diff line Loading @@ -38,17 +38,17 @@ class TestWriteIsisControlNetwork(unittest.TestCase): multi_index = pd.MultiIndex.from_tuples(list(zip(ids, ptype, serials, mtype)), names=['Id', 'Type', 'Serial Number', 'Measure Type']) columns = ['Random Number'] columns = ['x', 'y'] self.data_length = 5 data = np.random.randn(self.data_length) data = np.random.random((self.data_length, 2)) self.creation_time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) cnet = C(data, index=multi_index, columns=columns) io_controlnetwork.to_isis('test.net', cnet, mode='wb', targetname='Moon') self.header_message_size = 84 self.point_start_byte = 65620 self.header_message_size = 85 self.point_start_byte = 65621 def test_create_buffer_header(self): with open('test.net', 'rb') as f: Loading @@ -68,14 +68,14 @@ class TestWriteIsisControlNetwork(unittest.TestCase): self.assertEqual('Not modified', header_protocol.lastModified) #Repeating self.assertEqual([145, 99], header_protocol.pointMessageSizes) self.assertEqual([199, 135], header_protocol.pointMessageSizes) def test_create_point(self): with open('test.net', 'rb') as f: with open('test.net', 'rb') as f: f.seek(self.point_start_byte) for i, length in enumerate([145, 99]): for i, length in enumerate([199, 135]): point_protocol = cnf.ControlPointFileEntryV0002() raw_point = f.read(length) point_protocol.ParseFromString(raw_point) Loading @@ -95,10 +95,10 @@ class TestWriteIsisControlNetwork(unittest.TestCase): self.assertEqual(5, mpoints) points_bytes = find_in_dict(pvl_header, 'PointsBytes') self.assertEqual(244, points_bytes) self.assertEqual(334, points_bytes) points_start_byte = find_in_dict(pvl_header, 'PointsStartByte') self.assertEqual(65620, points_start_byte) self.assertEqual(65621, points_start_byte) def tearDown(self): os.remove('test.net') No newline at end of file autocnet/graph/network.py +84 −1 Original line number Diff line number Diff line from collections import Hashable import networkx as nx import pandas as pd from autocnet.control.control import C, POINT_TYPE, MEASURE_TYPE from autocnet.fileio import io_json class CandidateGraph(nx.DiGraph): class CandidateGraph(nx.Graph): """ A NetworkX derived directed graph to store candidate overlap images. Loading Loading @@ -44,6 +49,83 @@ class CandidateGraph(nx.DiGraph): adjacency_dict[n] = self.neighbors(n) io_json.write_json(adjacency_dict, outputfile) def add_matches(self, source_node, matches): """ Adds match data to a node and attributes the data to the appropriate edges, e.g. if A-B have a match, edge A-B is attributes with the pandas dataframe. Parameters ---------- source_node : str The identifier for the node matches : dataframe The pandas dataframe containing the matches """ #TODO: This really belongs in an outlier detection matcher class, not here. # Remove erroneous self neighbors matches = matches.loc[matches['matched_to'] != source_node] groups = matches.groupby('matched_to') for destination_node, group in groups: try: edge = self[source_node][destination_node] except: edge = self[destination_node][source_node] if 'matches' in edge.keys(): df = edge['matches'] edge['matches'] = pd.merge(df, matches, left_on='queryIdx', right_on='trainIdx') else: edge['matches'] = matches def to_cnet(self): """ Generate a control network (C) object from a graph Returns ------- cnet : C A control network object """ data = [] point_ids = [] serials = [] for source, destination, attributes in self.edges_iter(data=True): for i, row in attributes['matches'].iterrows(): # Get the source and destination x,y coordinates for matches source_idx = row['queryIdx_x'] source_keypoints = (self.node[source]['keypoints'][source_idx].pt[0], self.node[source]['keypoints'][source_idx].pt[1]) destination_idx = row['queryIdx_y'] destination_keypoints = (self.node[destination]['keypoints'][destination_idx].pt[0], self.node[destination]['keypoints'][destination_idx].pt[1]) data.append(source_keypoints) data.append(destination_keypoints) serials.append(source) serials.append(destination) point_ids.append(i) point_ids.append(i) point_types = [2] * len(point_ids) measure_types = [2] * len(point_ids) multi_index = pd.MultiIndex.from_tuples(list(zip(point_ids,point_types, serials, measure_types))) columns = ['x', 'y'] cnet = C(data, index=multi_index, columns=columns) # TODO: This method assumes a 2 image match and should be generalized to build an n-image C object return cnet @classmethod def from_adjacency(cls, inputfile): """ Loading @@ -68,3 +150,4 @@ class CandidateGraph(nx.DiGraph): adjacency_dict = io_json.read_json(inputfile) return cls(adjacency_dict) Loading
autocnet/control/control.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from time import gmtime, strftime import pandas as pd POINT_TYPE = 2 MEASURE_TYPE = 2 class CSeries(pd.Series): """ Loading
autocnet/examples/Apollo15/two_image_adjacency.json 0 → 100644 +2 −0 Original line number Diff line number Diff line {"AS15-M-0297_SML.png": ["AS15-M-0298_SML.png"], "AS15-M-0298_SML.png": ["AS15-M-0297_SML.png"]}
autocnet/fileio/io_controlnetwork.py +11 −5 Original line number Diff line number Diff line Loading @@ -144,18 +144,24 @@ class IsisStore(object): # Get the subset of the dataframe point = cnet.loc[point_id] try: point_spec.id = point_id except: point_spec.id = str(point_id) point_spec.type = FREEPOINT # Hard coded to free # A single extend call is cheaper than many add calls to pack points measure_iterable = [] for m in point.iterrows(): for name, measure in point.iterrows(): measure_spec = point_spec.Measure() serialnumber = m[0][1] mtype = m[0][2] measure_spec.serialnumber = serialnumber serial_number = name[1] mtype = name[2] measure_spec.serialnumber = serial_number measure_spec.type = mtype measure_spec.sample = measure.x measure_spec.line = measure.y measure_iterable.append(measure_spec) point_spec.measures.extend(measure_iterable) Loading
autocnet/fileio/tests/test_io_controlnetwork.py +8 −8 Original line number Diff line number Diff line Loading @@ -38,17 +38,17 @@ class TestWriteIsisControlNetwork(unittest.TestCase): multi_index = pd.MultiIndex.from_tuples(list(zip(ids, ptype, serials, mtype)), names=['Id', 'Type', 'Serial Number', 'Measure Type']) columns = ['Random Number'] columns = ['x', 'y'] self.data_length = 5 data = np.random.randn(self.data_length) data = np.random.random((self.data_length, 2)) self.creation_time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) cnet = C(data, index=multi_index, columns=columns) io_controlnetwork.to_isis('test.net', cnet, mode='wb', targetname='Moon') self.header_message_size = 84 self.point_start_byte = 65620 self.header_message_size = 85 self.point_start_byte = 65621 def test_create_buffer_header(self): with open('test.net', 'rb') as f: Loading @@ -68,14 +68,14 @@ class TestWriteIsisControlNetwork(unittest.TestCase): self.assertEqual('Not modified', header_protocol.lastModified) #Repeating self.assertEqual([145, 99], header_protocol.pointMessageSizes) self.assertEqual([199, 135], header_protocol.pointMessageSizes) def test_create_point(self): with open('test.net', 'rb') as f: with open('test.net', 'rb') as f: f.seek(self.point_start_byte) for i, length in enumerate([145, 99]): for i, length in enumerate([199, 135]): point_protocol = cnf.ControlPointFileEntryV0002() raw_point = f.read(length) point_protocol.ParseFromString(raw_point) Loading @@ -95,10 +95,10 @@ class TestWriteIsisControlNetwork(unittest.TestCase): self.assertEqual(5, mpoints) points_bytes = find_in_dict(pvl_header, 'PointsBytes') self.assertEqual(244, points_bytes) self.assertEqual(334, points_bytes) points_start_byte = find_in_dict(pvl_header, 'PointsStartByte') self.assertEqual(65620, points_start_byte) self.assertEqual(65621, points_start_byte) def tearDown(self): os.remove('test.net') No newline at end of file
autocnet/graph/network.py +84 −1 Original line number Diff line number Diff line from collections import Hashable import networkx as nx import pandas as pd from autocnet.control.control import C, POINT_TYPE, MEASURE_TYPE from autocnet.fileio import io_json class CandidateGraph(nx.DiGraph): class CandidateGraph(nx.Graph): """ A NetworkX derived directed graph to store candidate overlap images. Loading Loading @@ -44,6 +49,83 @@ class CandidateGraph(nx.DiGraph): adjacency_dict[n] = self.neighbors(n) io_json.write_json(adjacency_dict, outputfile) def add_matches(self, source_node, matches): """ Adds match data to a node and attributes the data to the appropriate edges, e.g. if A-B have a match, edge A-B is attributes with the pandas dataframe. Parameters ---------- source_node : str The identifier for the node matches : dataframe The pandas dataframe containing the matches """ #TODO: This really belongs in an outlier detection matcher class, not here. # Remove erroneous self neighbors matches = matches.loc[matches['matched_to'] != source_node] groups = matches.groupby('matched_to') for destination_node, group in groups: try: edge = self[source_node][destination_node] except: edge = self[destination_node][source_node] if 'matches' in edge.keys(): df = edge['matches'] edge['matches'] = pd.merge(df, matches, left_on='queryIdx', right_on='trainIdx') else: edge['matches'] = matches def to_cnet(self): """ Generate a control network (C) object from a graph Returns ------- cnet : C A control network object """ data = [] point_ids = [] serials = [] for source, destination, attributes in self.edges_iter(data=True): for i, row in attributes['matches'].iterrows(): # Get the source and destination x,y coordinates for matches source_idx = row['queryIdx_x'] source_keypoints = (self.node[source]['keypoints'][source_idx].pt[0], self.node[source]['keypoints'][source_idx].pt[1]) destination_idx = row['queryIdx_y'] destination_keypoints = (self.node[destination]['keypoints'][destination_idx].pt[0], self.node[destination]['keypoints'][destination_idx].pt[1]) data.append(source_keypoints) data.append(destination_keypoints) serials.append(source) serials.append(destination) point_ids.append(i) point_ids.append(i) point_types = [2] * len(point_ids) measure_types = [2] * len(point_ids) multi_index = pd.MultiIndex.from_tuples(list(zip(point_ids,point_types, serials, measure_types))) columns = ['x', 'y'] cnet = C(data, index=multi_index, columns=columns) # TODO: This method assumes a 2 image match and should be generalized to build an n-image C object return cnet @classmethod def from_adjacency(cls, inputfile): """ Loading @@ -68,3 +150,4 @@ class CandidateGraph(nx.DiGraph): adjacency_dict = io_json.read_json(inputfile) return cls(adjacency_dict)