Unverified Commit 2110895f authored by Lauren Adoram-Kershner's avatar Lauren Adoram-Kershner Committed by GitHub
Browse files

Fixing NetworkCandidateGraph.from_cnet() (#498)

* initial commit

* Getting PR to work locally
parent 07f506b3
Loading
Loading
Loading
Loading
+111 −38
Original line number Diff line number Diff line
@@ -1844,7 +1844,7 @@ class NetworkCandidateGraph(CandidateGraph):
                session.commit()

    @classmethod
    def from_filelist(cls, filelist, clear_db=False):
    def from_filelist(cls, filelist, config, clear_db=False):
        """
        Parse a filelist to add nodes to the database. Using the
        information in the database, then instantiate a complete,
@@ -1856,11 +1856,47 @@ class NetworkCandidateGraph(CandidateGraph):
                   If a list, this is a list of paths. If a str, this is
                   a path to a file containing a list of image paths
                   that is newline ("\\n") delimited.
        config : dict, str
                 configuration information; either a path to a yaml
                 file or a dictionary.

        clear_db : boolean
                   truncates all tables in the active database.

        Returns
        -------
        ncg : object
              A network candidate graph object

        See Also:
        --------
        config_from_dict: config documentation
        """
        obj = cls()

        if isinstance(config, str):
            config = parse_config(config)
        obj.config_from_dict(config)

        if clear_db:
            obj.clear_db()

        obj.add_from_filelist(filelist, clear_db=clear_db)

        return obj

    def add_from_filelist(self, filelist, clear_db=False):
        """
        Parse a filelist to add nodes to the database.

        Parameters
        ----------
        filelist : list, str
                   If a list, this is a list of paths. If a str, this is
                   a path to a file containing a list of image paths
                   that is newline ("\\n") delimited.
        clear_db : boolean
                   truncates all tables in the active database.
        """
        if isinstance(filelist, list):
            pass
@@ -1870,7 +1906,7 @@ class NetworkCandidateGraph(CandidateGraph):
            warnings.warn('Unable to parse the passed filelist')

        if clear_db:
            cls.clear_db()
            self.clear_db()

        total=len(filelist)
        for cnt, f in enumerate(filelist):
@@ -1878,12 +1914,28 @@ class NetworkCandidateGraph(CandidateGraph):
            # images in the DB
            print('loading {} of {}'.format(cnt+1, total))
            image_name = os.path.basename(f)
            NetworkNode(image_path=f, image_name=image_name)
            node = NetworkNode(image_path=f, image_name=image_name)
            node.parent = self
            node.populate_db()

        obj = cls.from_database()
        self.from_database()
        # Execute the computation to compute overlapping geometries
        obj._execute_sql(compute_overlaps_sql)
        return obj
        self._execute_sql(compute_overlaps_sql)

    def add_image(self, img_path):
        """
        Upload a single image to NetworkCandidateGraph associated DB.

        Parameters
        ----------
        img_path: str
                  absolute path to image
        """
        image_name = os.path.basename(img_path)
        node = NetworkNode(image_path=f, image_name=image_name)
        node.parent = self
        node.populate_db()


    def copy_images(self, newdir):
        """
@@ -1942,11 +1994,6 @@ class NetworkCandidateGraph(CandidateGraph):
                       An optional string to select a subset of the images in the
                       database specified in the config.

        Returns
        -------
        obj : obj
              A network candidate graph.

        Example
        -------
        >>> ncg = NetworkCandidateGraph()
@@ -2043,8 +2090,7 @@ class NetworkCandidateGraph(CandidateGraph):
        # Setup the edges
        self._setup_edges()

    @staticmethod
    def clear_db(tables=None):
    def clear_db(self, tables=None):
        """
        Truncate all of the database tables and reset any
        autoincrement columns to start with 1.
@@ -2054,8 +2100,7 @@ class NetworkCandidateGraph(CandidateGraph):
        table : str or list of str, optional
                the table name of a list of table names to truncate
        """
        session = Session()
        session.rollback() # In case any transactions are not done
        with self.session_scope() as session:
            if tables:
                if isinstance(tables, str):
                    tables = [tables]
@@ -2064,13 +2109,14 @@ class NetworkCandidateGraph(CandidateGraph):

            for t in tables:
                if t != 'spatial_ref_sys':
                    try:
                        session.execute(f'TRUNCATE TABLE {t} CASCADE')
                    except Exception as e:
                        raise RuntimeError(f'Failed to truncate table {t}, {t} not modified').with_traceback(e.__traceback__)
                    try:
                        session.execute(f'ALTER SEQUENCE {t}_id_seq RESTART WITH 1')
                    except Exception as e:
                warnings.warn(f'Failed to truncate table {t}, {t} not modified')
                session.rollback()
        session.commit()
        session.close()
                        warnings.warn(f'Failed to reset primary id sequence for table {t}')

    def place_points_from_cnet(self, cnet):
        semi_major, semi_minor = self.config["spatial"]["semimajor_rad"], self.config["spatial"]["semiminor_rad"]
@@ -2121,13 +2167,39 @@ class NetworkCandidateGraph(CandidateGraph):
        session.close()

    @classmethod
    def from_cnet(cls, cnet, filelist):
    def from_cnet(cls, cnet, filelist, config):
        """
        Instantiates and populates a NetworkCandidateGraph from an
        ISIS control network and corresponding cube list.

        Parameters
        ----------
        cnet:  str
               path to control network file from which you want to populate
               the NetworkCandidateGraph.

        filelist:  str
                   path to file containing list of cubes associated with
                   the control network file.

        config : dict, str
                 configuration information; either a path to a yaml
                 file or a dictionary.

        Returns
        -------
        obj:  NetworkCandidateGraph
             The NetworkCandidateGraph populated with the points and measures
             from the control network and the images from the filelist.

        See Also:
        --------
        config_from_dict: config documentation
        """
        networkobj = cls.from_filelist(filelist)
        networkobj.place_points_from_cnet(cnet)
        return networkobj
        obj = cls.from_filelist(filelist, config)
        obj.place_points_from_cnet(cnet)

        return obj

    @property
    def measures(self):
@@ -2137,10 +2209,11 @@ class NetworkCandidateGraph(CandidateGraph):
    @property
    def queue_length(self):
        """
        Returns the length of the processing queue. Jobs are left on the
        queue if a cluster job is cancelled. Those cancelled jobs are then
        called on next cluster job launch, causing failures. This method provides
        a quick check for left over jobs.
        Returns the length of the processing queue.

        Jobs are left on the queue if a cluster job is cancelled. Those cancelled
        jobs are then called on next cluster job launch, causing failures. This
        method provides a check for left over jobs.
        """
        llen = self.redis_queue.llen(self.config['redis']['processing_queue'])
        return llen
+11 −12
Original line number Diff line number Diff line
@@ -514,7 +514,7 @@ class NetworkNode(Node):

    def populate_db(self):
        with self.parent.session_scope() as session:
            res = session.query(Images).filter(Images.path == kwargs['image_path']).first()
            res = session.query(Images).filter(Images.path == self['image_path']).first()
            if res:
                # Image already exists
                return
@@ -529,17 +529,16 @@ class NetworkNode(Node):
            warnings.warn('Unable to generate image footprint.\n{}'.format(e))
            fp = None
        # Create the image
        i = Images(name=kwargs['image_name'],
                   path=kwargs['image_path'],
        i = Images(name=self['image_name'],
                   path=self['image_path'],
                   geom=fp,
                   keypoints=kps,
                   #cameras=cam,
                   serial=self.isis_serial,
                   cam_type=cam_type)

        session = self.parent.Session()
        i.create(session)
        session.close()
        with self.parent.session_scope() as session:
            session.add(i)

    def _from_db(self, table_obj, key='image_id'):
        """
+1 −6
Original line number Diff line number Diff line
@@ -200,15 +200,10 @@ class Images(BaseMixin, Base):
    measures = relationship("Measures")

    def __repr__(self):
        try:
            footprint = to_shape(self.geom).__geo_interface__
        except:
            footprint = None
        return json.dumps({'id':self.id,
                'name':self.name,
                'path':self.path,
                'geom':footprint,
                'footprint_bodyfixed':self.footprint_bodyfixed})
                'geom':self.geom.wkt})

    @hybrid_property
    def geom(self):