Commit 387de77f authored by Jay's avatar Jay
Browse files

Merges environment

parents 4b507353 6ed6297a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ unit-test-job:
    - conda init
    - source /root/.bashrc
    - source activate autocnet_env
    - pip install -r test_requirements.txt
    - psql -h $POSTGRES_HOST -c 'create database template_postgis;' -U postgres ;
    - psql template_postgis -h $POSTGRES_HOST -U postgres -c 'create extension postgis';
    - psql template_postgis -U $POSTGRES_USER -h $POSTGRES_HOST -c 'create extension postgis_topology';
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ When preparing for a bug fix release create a new 2nd heading above the Fixed
heading to indicate that only the bug fixes and security fixes are in the bug fix
release.
-->
## [Unreleased]

### Fixed
- `place_points_in_overlap` bug where if any of the points in the overlap failed to project into an image, all points in the overlap were lost. This was caused by #580, which allowed for multiple (a list) of inputs. The error handling was removed from the `image_to_ground` call so the `except` in `place_points_in_overlap` was never called.
## [1.0.0-rc2]

### Changed
+5 −1
Original line number Diff line number Diff line
@@ -459,6 +459,7 @@ def distribute_points_in_geom(geom, method="classic",
                              nspts_func=lambda x: ceil(round(x,1)*10),
                              ewpts_func=lambda x: ceil(round(x,1)*5),
                              Session=None,
                              ratio_size=0.1,
                              **kwargs):
    """
    Given a geometry, attempt a basic classification of the shape.
@@ -486,6 +487,9 @@ def distribute_points_in_geom(geom, method="classic",

    ewpts_func : obj
                 Function taking a Number and returning an int
    ratio_size : float
                 A number that represent the minimum size the
                 ratio is set at to be considered a sliver.

    Returns
    -------
@@ -532,7 +536,7 @@ def distribute_points_in_geom(geom, method="classic",
        ew = True

    # Decision Tree
    if ratio < 0.1 and geom.area < 0.01:
    if ratio < ratio_size and geom.area < 0.01:
        # Class: Slivers - ignore.
        return np.array([])
    elif geom.area <= 0.004 and ratio >= 0.25:
+30 −13
Original line number Diff line number Diff line
@@ -6,11 +6,12 @@ import geopandas as gpd
from shapely.geometry import Point

from autocnet.matcher import subpixel as sp
from autocnet.transformation.spatial import reproject

from plio.io.io_controlnetwork import to_isis, write_filelist
from plio.utils import covariance

def compute_covariance(df, latsigma, lonsigma, radsigma, radius):
def compute_covariance(df, dem, latsigma, lonsigma, radsigma):
    """
    Compute the covariance matrices for constrained or fixed points.

@@ -19,6 +20,9 @@ def compute_covariance(df, latsigma, lonsigma, radsigma, radius):
    df : pd.DataFrame
         with columns pointtype, adjustedY, and adjustedX
    
    dem : ~autocnet.spatial.surface.EllipsoidDem or ~autocnet.spatial.surface.GdalDem
          Digital Elevation Model (DEM) object described the target body

    latsigma : int/float
               The estimated sigma (error) in the latitude direction

@@ -27,19 +31,31 @@ def compute_covariance(df, latsigma, lonsigma, radsigma, radius):

    radsigma : int/float
               The estimated sigma (error) in the radius direction

    radius : int/float
             The body semimajor radius
    """
    def compute_covar(row, latsigma, lonsigma, radsigma, radius):

    semi_major = dem.a
    semi_minor = dem.c

    def compute_covar(row, latsigma, lonsigma, radsigma, semi_major, semi_minor):
        if row['pointtype'] == 3 or row['pointtype'] == 4:
            return covariance.compute_covariance(row['adjustedY'], 
                                                    row['adjustedX'], 
            
            if semi_minor is None:
                semi_minor = semi_major

            x,y,z = row[['aprioriX', 'aprioriY', 'aprioriZ']]
            lon, lat, _ = reproject([x,y,z],
                                        semi_major, semi_minor,
                                        'geocent', 'latlon')
            # compute_covariance requires the radius, autocnet operates in height
            radius = dem.get_radius(lat, lon)

            return covariance.compute_covariance(lat,
                                                 lon,
                                                 radius,
                                                 latsigma=latsigma,
                                                 lonsigma=lonsigma,
                                                 radsigma=radsigma,
                                                    semimajor_axis=radius)
                                                 semimajor_axis=semi_major)
        return []

    df['aprioriCovar'] = df.apply(compute_covar, 
@@ -47,7 +63,8 @@ def compute_covariance(df, latsigma, lonsigma, radsigma, radius):
                                  args=(latsigma,
                                  lonsigma,
                                  radsigma,
                                  radius))
                                  semi_major,
                                  semi_minor))
    return df

def identify_potential_overlaps(cg, cn, overlap=True):
+57 −18
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import os
from shutil import copyfile
import threading
from time import gmtime, strftime, time, sleep
import time
import logging
from itertools import combinations

@@ -1476,8 +1477,8 @@ class CandidateGraph(nx.Graph):
        df["serialnumber"] = serials

        # only populate the new columns for ground points. Otherwise, isis will
        #recalculate the control point lat/lon from control measures which where
        #"massaged" by the phase and template matcher.
        # recalculate the control point lat/lon from the average location of the 
        # control measures projection to ground after autocnet matching.
        for i, group in df.groupby('point_id'):
            zero_group = group.iloc[0]
            apriori_geom = np.array(point_info(self.nodes[zero_group.image_index]['data'].geodata.file_name, zero_group.x, zero_group.y, 'image')['BodyFixedCoordinate'].value) * 1000
@@ -2110,10 +2111,12 @@ class NetworkCandidateGraph(CandidateGraph):

    def to_isis(self,
                path,
                dem = None,
                flistpath=None,
                latsigma=10,
                lonsigma=10,
                radsigma=15,
                ground_xyz=None,
                **db_kwargs):
        """
        Write a NetworkCandidateGraph to an ISIS control network
@@ -2123,6 +2126,9 @@ class NetworkCandidateGraph(CandidateGraph):
        path : str
               Outpath to write the control network

        dem : ~autocnet.spatial.surface.EllipsoidDem or ~autocnet.spatial.surface.GdalDem
              Digital Elevation Model (DEM) object described the target body

        flishpath : str
                    Outpath to write the associated file list. If None (default),
                    the file list is written alongside the control network
@@ -2136,8 +2142,10 @@ class NetworkCandidateGraph(CandidateGraph):
        radsigma : int/float
                The estimated sigma (error) in the radius direction

        radius : int/float
                The body semimajor radius
        ground_xyz: str
                    Path to the file that determined image coordinates of ground points,
                    if different than dem argument. This is the file typically used in 
                    the image registration step of ground points creation.

        db_kwargs : dict
                    Kwargs that are passed to the io.db.controlnetwork.db_to_df function
@@ -2151,15 +2159,26 @@ class NetworkCandidateGraph(CandidateGraph):
                 of paths to the images being included in the control network

        """

        if dem is None:
            dem_file = None
            log.warning(f'No dem argument passed; covariance matrices will be computed for the points.')
        else:
            if isinstance(dem, EllipsoidDem): # not sure about this
                dem_file = f'EllipsoidDem a={dem.a} b {dem.b} c={dem.c}'
            elif isinstance(dem, GdalDem):
                dem_file = dem.dem.file_name

        # Read the cnet from the db
        df = io_controlnetwork.db_to_df(self.engine, **db_kwargs)
        df = io_controlnetwork.db_to_df(self, ground_radius=dem_file, ground_xyz=ground_xyz, **db_kwargs)

        # Add the covariance matrices to ground measures
        if dem is not None:
            df = control.compute_covariance(df,
                                            dem,
                                            latsigma,
                                            lonsigma,
                                        radsigma,
                                        self.config['spatial']['semimajor_rad'])
                                            radsigma)

        if flistpath is None:
            flistpath = os.path.splitext(path)[0] + '.lis'
@@ -2246,7 +2265,7 @@ class NetworkCandidateGraph(CandidateGraph):

        return obj

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

@@ -2270,17 +2289,37 @@ class NetworkCandidateGraph(CandidateGraph):
            self.clear_db()

        total=len(filelist)
        db_images = []
        for cnt, f in enumerate(filelist):
            # Create the nodes in the graph. Really, this is creating the
            # images in the DB
            log.info('loading {} of {}'.format(cnt+1, total))
            self.add_image(f)

            image_name = os.path.basename(f)
            node = NetworkNode(image_path=f, image_name=image_name)
            node.parent = self
            
            i = node.create_db_element(exist_check=exist_check)
            db_images.append(i)
            break

            if cnt%1000 == 0:
                log.info('uploading 1000 images to database...')
                with self.session_scope() as session:
                    session.add_all(db_images)
                    db_images = []
            
        with self.session_scope() as session:
            log.info(f'uploading final {len(db_images)} images to database.')
            session.add_all(db_images)

        

        self.from_database()
        # Execute the computation to compute overlapping geometries
        self._execute_sql(sql.compute_overlaps_sql)

    def add_image(self, img_path):
    def add_image(self, img_path, exist_check=True, add_keypoints=False):
        """
        Upload a single image to NetworkCandidateGraph associated DB.

@@ -2297,7 +2336,7 @@ class NetworkCandidateGraph(CandidateGraph):
        image_name = os.path.basename(img_path)
        node = NetworkNode(image_path=img_path, image_name=image_name)
        node.parent = self
        node.populate_db()
        node.populate_db(exist_check=exist_check, add_keypoints=add_keypoints)
        return node['node_id']

    def copy_images(self, newdir):
@@ -2776,7 +2815,7 @@ class NetworkCandidateGraph(CandidateGraph):
            # return missing image id pairs
            return [e for e in all_edges if e not in graph.edges]

    def cluster_propagate_control_network(self,
    def cluster_propagate_ground_points(self,
                                          base_cnet,
                                          walltime='00:20:00',
                                          chunksize=1000,
@@ -2915,8 +2954,8 @@ class NetworkCandidateGraph(CandidateGraph):
    def subpixel_regiter_mearure(self, measureid, **kwargs):
        subpixel.subpixel_register_measure(self.Session, measureid, **kwargs)

    def propagate_control_network(self, control_net, **kwargs):
        cim.propagate_control_network(self.Session,
    def propagate_ground_points(self, control_net, **kwargs):
        cim.propagate_ground_points(self.Session,
                                      self.config,
                                      self.dem,
                                      control_net)
Loading