Unverified Commit cc64a7fa authored by Jesse Mapel's avatar Jesse Mapel Committed by GitHub
Browse files

Added ignore property to NetworkNodes (#419)

* Added ignore property to NetworkNodes

* cleaned up trigger function:

* Added regular Node ignore

* doc update

* Added apply test

* Fixed apply and test

* Added db trigger test

* More test updates

* Trigger syntax fix

* Fixed query size

* Review comments
parent e386d11c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -585,7 +585,8 @@ class CandidateGraph(nx.Graph):
    def apply(self, function, on='edge', out=None, args=(), **kwargs):
        """
        Applys a function to every node or edge, returns collected return
        values.
        values. If applying a functions to nodes, then all ignored nodes
        will be skipped.

        TODO: Merge with apply_func_to_edges?

@@ -626,6 +627,8 @@ class CandidateGraph(nx.Graph):
        if options[on] == self.edges_iter:
            obj = 2
        for elem in options[on](data=True):
            if getattr(elem[obj], 'ignore', False):
                continue
            res.append(function(elem[obj], *args, **kwargs))

        if out:
+24 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ class Node(dict, MutableMapping):
    masks : set
            A list of the available masking arrays

    ignore : bool
             If the image is flagged as ignored and will be skipped in processing

    isis_serial : str
                  If the input images have PVL headers, generate an
                  ISIS compatible serial number
@@ -65,6 +68,7 @@ class Node(dict, MutableMapping):
        self['node_id'] = node_id
        self['hash'] = image_name
        self.masks = pd.DataFrame()
        self.ignore = False

    @property
    def camera(self):
@@ -695,6 +699,26 @@ class NetworkNode(Node):
        session.close()
        return res

    @property
    def ignore(self):
        """
        Gets the ignore flag from the Images table
        """
        session = Session()
        res = self._from_db(Images, key='id')
        return res.ignore

    @ignore.setter
    def ignore(self, ignore):
        """
        Sets the ignore flag in the Images table
        """
        session = Session()
        res = session.query(Images).filter(getattr(Images,'id') == self['node_id']).one()
        res.ignore = ignore
        session.commit()
        session.close()

    def generate_vrt(self, **kwargs):
        """
        Using the image footprint, generate a VRT to that is usable inside
+19 −0
Original line number Diff line number Diff line
@@ -376,6 +376,25 @@ def test_apply(graph):

    for matches in results:
        assert len(matches) == 3
    assert len(matches) == len(graph.edges)

def test_apply_on_nodes(graph):
    def set_test_attribute(n):
        n.test_attribute = 1

    def get_test_attribute(n):
        return n.test_attribute

    for _, data in graph.nodes(data=True):
        if data['data']['image_name'] == 'AS15-M-0297_SML.png':
            data['data'].ignore = True

    graph.apply(set_test_attribute, on='node')
    results = graph.apply(get_test_attribute, on='node')

    assert len(results) == len(graph.nodes) - 1
    for test_att in results:
        assert test_att == 1

def test_tofilelist(graph):
    flist = graph.to_filelist()
+4 −2
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ class Edges(BaseMixin, Base):
    destination = Column(Integer)
    ring = Column(ArrayType())
    fundamental = Column(ArrayType())
    ignore = Column(Boolean)
    ignore = Column(Boolean, default=False)
    masks = Column(Json())

class Costs(BaseMixin, Base):
@@ -376,7 +376,7 @@ class Measures(BaseMixin, Base):
        self._measuretype = v

if isinstance(Session, sqlalchemy.orm.sessionmaker):
    from autocnet.io.db.triggers import valid_point_function, valid_point_trigger, valid_geom_function, valid_geom_trigger
    from autocnet.io.db.triggers import valid_point_function, valid_point_trigger, valid_geom_function, valid_geom_trigger, ignore_image_function, ignore_image_trigger

    # Create the database
    if not database_exists(engine.url):
@@ -389,6 +389,8 @@ if isinstance(Session, sqlalchemy.orm.sessionmaker):
        event.listen(Measures.__table__, 'after_create', valid_point_trigger)
        event.listen(Base.metadata, 'before_create', valid_geom_function)
        event.listen(Images.__table__, 'after_create', valid_geom_trigger)
        event.listen(Base.metadata, 'before_create', ignore_image_function)
        event.listen(Images.__table__, 'after_create', ignore_image_trigger)

    Base.metadata.bind = engine
    # If the table does not exist, this will create it. This is used in case a
+24 −0
Original line number Diff line number Diff line
@@ -198,3 +198,27 @@ def test_fix_bad_geom(session):
    resp = session.query(model.Images).filter(model.Images.id==i.id).one()
    assert resp.ignore == False
    assert resp.geom == MultiPolygon([Polygon([(0,0), (0,1), (1,1), (1,0), (0,0) ])])

@pytest.mark.parametrize("measure_data, point_data, image_data", [(
    [{'id': 1, 'pointid': 1, 'imageid': 1, 'serial': 'ISISSERIAL1', 'measuretype': 3, 'sample': 0, 'line': 0},
     {'id': 2, 'pointid': 1, 'imageid': 2, 'serial': 'ISISSERIAL2', 'measuretype': 3, 'sample': 0, 'line': 0},
     {'id': 3, 'pointid': 1, 'imageid': 3, 'serial': 'ISISSERIAL3', 'measuretype': 3, 'sample': 0, 'line': 0},
     {'id': 4, 'pointid': 1, 'imageid': 4, 'serial': 'ISISSERIAL4', 'measuretype': 3, 'sample': 0, 'line': 0}],
    {'id':1,
     'pointtype':2},
    [{'id':1, 'serial': 'ISISSERIAL1'},
     {'id':2, 'serial': 'ISISSERIAL2'},
     {'id':3, 'serial': 'ISISSERIAL3'},
     {'id':4, 'serial': 'ISISSERIAL4'}])])
def test_ignore_image(session, measure_data, point_data, image_data):
    for data in image_data:
        model.Images.create(session, **data)
    model.Points.create(session, **point_data)
    for data in measure_data:
        model.Measures.create(session, **data)
    image_resp = session.query(model.Images).filter(model.Images.id == 1).first()
    image_resp.ignore = True
    ignored_measures_resp = session.query(model.Measures).filter(model.Measures.ignore == True).first()
    assert ignored_measures_resp.imageid == 1
    valid_measures_resp = session.query(model.Measures).filter(model.Measures.ignore == False)
    assert valid_measures_resp.count() == 3
Loading