Commit a4a4eed8 authored by Jay's avatar Jay
Browse files

Updates for subpixel alignment, changes affine to projective transform to capture reflection.

parent 5f29d316
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
#!/usr/bin/env python

import argparse
import copy
import os
import json
import sys
import logging

from io import StringIO
from contextlib import redirect_stdout
import sys

from redis import StrictRedis

from autocnet.graph.network import NetworkCandidateGraph
from autocnet.graph.node import NetworkNode
from autocnet.graph.edge import NetworkEdge
from autocnet.io.db.model import Points, Measures, Overlay
from autocnet.utils.utils import import_func
from autocnet.utils.serializers import JsonEncoder, object_hook
from autocnet.io.db.model import JobsHistory
from autocnet.utils.serializers import object_hook

logging.basicConfig(stream=sys.stdout, level=logging.INFO)
log = logging.getLogger(__name__)

def parse_args():  # pragma: no cover
@@ -102,7 +97,7 @@ def process(msg):
        # For now, pass all the potential config items through
        # most funcs will simply discard the unnecessary ones.
        msg['kwargs']['ncg'] = ncg
        msg['kwargs']['Session'] = ncg.Session
        msg['kwargs']['session'] = ncg.Session

    # Now run the function.
    res = func(*msg['args'], **msg['kwargs'])
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ def process(msg):
        # For now, pass all the potential config items through
        # most funcs will simply discard the unnecessary ones.
        msg['kwargs']['ncg'] = ncg
        msg['kwargs']['Session'] = ncg.Session
        msg['kwargs']['session'] = ncg.Session

    # Now run the function.
    res = func(*msg['args'], **msg['kwargs'])
+12 −9
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ class CandidateGraph(nx.Graph):
        'keypoint_index' : int
    }

    def __init__(self, *args, basepath=None, node_id_map=None, overlaps=False, cam_type='isis', **kwargs):
    def __init__(self, *args, basepath=None, node_id_map=None, overlaps=False, **kwargs):
        super(CandidateGraph, self).__init__(*args, **kwargs)

        self.graph['creationdate'] = strftime("%Y-%m-%d %H:%M:%S", gmtime())
@@ -131,7 +131,7 @@ class CandidateGraph(nx.Graph):
                node_id = self.graph['node_counter']
                self.graph['node_counter'] += 1
            n['data'] = self.node_factory(
                image_name=i, image_path=image_path, node_id=node_id, cam_type=cam_type)
                image_name=i, image_path=image_path, node_id=node_id)

            self.graph['node_name_map'][i] = node_id

@@ -1638,6 +1638,14 @@ class NetworkCandidateGraph(CandidateGraph):
                retries += 1
                sleep(retries ** sleeptime)

    # def _setup_nodes(self):
    #     with self.session_scope() as session:
    #         res = session.query(Images.path, Images.cam_type, Images.dem, Images.dem_type).all()
    #         for r in res:
    #             self.nodes[r[0]]['cam_type'] = r[1]
    #             self.nodes[r[0]]['dem'] = r[2]
    #             self.nodes[r[0]]['dem_type'] = r[3]

    def _setup_edges(self):
        with self.session_scope() as session:
            res = session.query(Edges).all()
@@ -2089,14 +2097,10 @@ class NetworkCandidateGraph(CandidateGraph):
        if just_stage:
            return command

        if queue == None:
            queue = self.config['cluster']['queue']

        submitter = Slurm(command,
                     job_name=jobname,
                     mem_per_cpu=self.config['cluster']['processing_memory'],
                     time=walltime,
                     partition=queue,
                     ntasks=ntasks,
                     output=log_dir+f'/autocnet.{function}-%j')

@@ -2461,7 +2465,7 @@ class NetworkCandidateGraph(CandidateGraph):
        if overlaps:
            self._execute_sql(sql.compute_overlaps_sql)

    def from_database(self, query_string=sql.select_pub_image, cam_type='isis'):
    def from_database(self, query_string=sql.select_pub_image):
        """
        This is a constructor that takes the results from an arbitrary query string,
        uses those as a subquery into a standard polygon overlap query and
@@ -2509,7 +2513,7 @@ class NetworkCandidateGraph(CandidateGraph):
                    adjacency[spath].append(dpath)

        # Add nodes that do not overlap any images
        self.__init__(adjacency, node_id_map=adjacency_lookup, cam_type=cam_type)
        self.__init__(adjacency, node_id_map=adjacency_lookup)

        # Setup the edges
        self._setup_edges()
@@ -2877,7 +2881,6 @@ class NetworkCandidateGraph(CandidateGraph):
                     job_name='cross_instrument_matcher',
                     mem_per_cpu=config['cluster']['processing_memory'],
                     time=walltime,
                     partition=config['cluster']['queue'],
                     output=config['cluster']['cluster_log_dir']+'/autocnet.cim-%j')
        job_counter = len(groups.items())
        submitter.submit(array='1-{}'.format(job_counter))
+1 −82
Original line number Diff line number Diff line
@@ -116,13 +116,11 @@ class Node(dict, MutableMapping):
        NodeID: {}
        Image Name: {}
        Image PATH: {}
        Number Keypoints: {}
        Available Masks : {}
        Type: {}
        Sensor Model Type: {}
        DEM: {}
        """.format(self['node_id'], self['image_name'], self['image_path'],
                   self.nkeypoints, self.masks, self.__class__,
                   self.__class__,
                   self['cam_type'], self['dem'])

    def __hash__(self): #pragma: no cover
@@ -630,55 +628,6 @@ class NetworkNode(Node):
        res = self._from_db(Keypoints)
        return res.nkeypoints if res is not None else 0

    def create_camera(self, url):
        """
        Creates a CSM sensor for the node and serializes the state
        to the DB,

        Parameters
        ----------
        url : str
              The URI to a service that can create an ISD to instantiate
              a sensor.
        """
        raise NotImplementedError

        # TODO: This should pass the straight metadata and not mess with mundging it.
        label = pvl.dumps(self.geodata.metadata).decode()
        response = requests.post(url, json={'label':label})
        response = response.json()
        model_name = response.get('name_model', None)
        if model_name is None:
            return
        isdpath = os.path.splitext(self['image_path'])[0] + '.json'
        try:
            with open(isdpath, 'w') as f:
                json.dump(response, f)
        except Exception as e:
           log.warning('Failed to write JSON ISD for image {}.\n{}'.format(self['image_path'], e))
        isd = csmapi.Isd(self['image_path'])
        plugin = csmapi.Plugin.findPlugin('UsgsAstroPluginCSM')
        self._camera = plugin.constructModelFromISD(isd, model_name)
        serialized_camera = self._camera.getModelState()

        cam = Cameras(camera=serialized_camera, image_id=self['node_id'])
        return cam

    @property
    def camera(self):
        """
        Get the camera object from the database.
        """
        # TODO: This should use knoten once it is stable.
        import csmapi
        if not getattr(self, '_camera', None):
            res = self._from_db(Cameras)
            plugin = csmapi.Plugin.findPlugin('UsgsAstroPluginCSM')
            if res is not None:
                self._camera = plugin.constructModelFromState(res.camera)
        return self._camera

    
    def footprint_from_database(self):
        with self.parent.session_scope() as session:
            res = session.query(Images).filter(Images.id == self['node_id']).first()
@@ -696,36 +645,6 @@ class NetworkNode(Node):
        cam_type = 'isis'
        return footprint_latlon, cam_type

    def footprint_from_csm(self):
        boundary = generate_boundary(self.geodata.raster_size[::-1])  # yx to xy
        footprint_latlon = generate_latlon_footprint(self.camera,
                                                        boundary,
                                                        dem=parent.dem)
        footprint_latlon.FlattenTo2D()
        cam_type = 'csm'
        return footprint_latlon, cam_type

    def generate_footprint(self, exist_check=True):        
        footprint_latlon = cam_type = None

        if exist_check:
            footprint_latlon, cam_type = self.footprint_from_database()

        # not in database, create footprint
        if footprint_latlon is None and cam_type is None:
            if utils.find_in_dict(self.geodata.metadata, "Polygon"):
                # get ISIS footprint if possible
                t1 = time.time()
                footprint_latlon, cam_type = self.footprint_from_isis()
                t2 = time.time()
            else:
                # Get CSM footprint
                t1 = time.time()
                footprint_latlon, cam_type = self.footprint_from_csm()
                t2 = time.time()
       
        return footprint_latlon, cam_type

    @property
    def footprint(self):
        if not hasattr(self, '_footprint'):
+1 −1
Original line number Diff line number Diff line
@@ -565,7 +565,7 @@ class Points(Base, BaseMixin):
                apriori=point_geom,
                adjusted=point_geom,
                pointtype=point_type, # Would be 3 or 4 for ground
                cam_type='isis',
                cam_type=reference_node['cam_type'],
                reference_index=0)
        
        # Create the measure for the reference image and add it to the point
Loading