Commit ab118e24 authored by acpaquette's avatar acpaquette Committed by jlaura
Browse files

Jigsaw Reingest (#317)

* Initial addition of the jigsaw reingest

* Adds testing for jigsaw ingestion

* Update jigsaw reingest to use a session argument vs creating a new session
parent ba2bde7c
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -1480,6 +1480,40 @@ WHERE points.active = True AND measures.active=TRUE AND measures.jigreject=FALSE
        cnet.to_isis(path, df, self.serials())
        cnet.write_filelist(self.files, path=flistpath)

    @staticmethod
    def update_from_jigsaw(session, path):
        """
        Updates the measures table in the database with data from
        a jigsaw bundle adjust

        Parameters
        ----------
        path : str
               Full path to a bundle adjusted isis control network
        """
        # Ingest isis control net as a df and do some massaging
        data = cnet.from_isis(path)
        data['jigsawFullRejected'] = data['pointJigsawRejected'] | data['jigsawRejected']
        data_to_update = data[['id', 'serialnumber', 'jigsawFullRejected', 'sampleResidual', 'lineResidual', 'samplesigma', 'linesigma', 'adjustedCovar', 'apriorisample', 'aprioriline']]
        data_to_update = data_to_update.rename(columns = {'serialnumber': 'serial', 'jigsawFullRejected': 'jigreject', 'sampleResidual': 'sampler', 'lineResidual': 'liner', 'adjustedCovar': 'covar'})
        data_to_update['covar'] = data_to_update['covar'].apply(lambda row : list(row))
        data_to_update['id'] = data_to_update['id'].apply(lambda row : int(row))

        # Generate a temp table, update the real table, then drop the temp table
        data_to_update.to_sql('temp_measures', engine, if_exists='replace', index_label='serialnumber', index = False)

        sql = """
        UPDATE measures AS f
        SET jigreject = t.jigreject, sampler = t.sampler, liner = t.liner, samplesigma = t.samplesigma, linesigma = t.linesigma, apriorisample = t.apriorisample, aprioriline = t.aprioriline
        FROM temp_measures AS t
        WHERE f.serial = t.serial AND f.pointid = t.id;

        DROP TABLE temp_measures;
        """

        session.execute(sql)
        session.commit()

    @classmethod
    def from_filelist(cls, filelist):
        """
+34 −3
Original line number Diff line number Diff line
@@ -2,12 +2,15 @@ from datetime import datetime
import json

import numpy as np
import pandas as pd
import pytest
import sqlalchemy
from shapely.geometry import Polygon, Point
from unittest.mock import MagicMock, patch

from autocnet.io.db import model
from autocnet import Session, engine
from autocnet.graph.network import NetworkCandidateGraph

@pytest.fixture
def tables():
@@ -22,7 +25,7 @@ def session(tables, request):
        for t in reversed(tables):
            session.execute(f'TRUNCATE TABLE {t} CASCADE')
            # Reset the autoincrementing
            if t in ['Images', 'Cameras', 'Matches']:
            if t in ['Images', 'Cameras', 'Matches', 'Measures']:
                session.execute(f'ALTER SEQUENCE {t}_id_seq RESTART WITH 1')
        session.commit()

@@ -45,6 +48,9 @@ def test_matches_exists(tables):
def test_cameras_exists(tables):
    assert model.Cameras.__tablename__ in tables

def test_measures_exists(tables):
    assert model.Measures.__tablename__ in tables

def test_create_camera_without_image(session):
    with pytest.raises(sqlalchemy.exc.IntegrityError):
        model.Cameras.create(session, **{'image_id':1})
@@ -134,6 +140,31 @@ def test_json_encoder(data, serialized):
    res = json.loads(res)
    if isinstance(res['foo'], list):
        res['foo'] = sorted(res['foo'])
    print(res)

    assert res == serialized

@pytest.mark.parametrize("measure_data, point_data, image_data", [({'id': 1, 'pointid': 1, 'imageid': 1, 'serial': 'ISISSERIAL', 'measuretype': 3, 'sample': 0, 'line': 0},
                                                                   {'id':1, 'pointtype':2},
                                                                   {'id':1, 'serial': 'ISISSERIAL'})])
@patch('plio.io.io_controlnetwork.from_isis', return_value = pd.DataFrame.from_dict({'id': [1],
                                                                                     'serialnumber': ['ISISSERIAL'],
                                                                                     'pointJigsawRejected': [False],
                                                                                     'jigsawRejected': [False],
                                                                                     'sampleResidual': [0.1],
                                                                                     'lineResidual': [0.1],
                                                                                     'samplesigma': [0],
                                                                                     'linesigma': [0],
                                                                                     'adjustedCovar': [[]],
                                                                                     'apriorisample': [0],
                                                                                     'aprioriline': [0]}))
def test_jigsaw_append(mockFunc, session, measure_data, point_data, image_data):
    model.Images.create(session, **image_data)
    model.Points.create(session, **point_data)
    model.Measures.create(session, **measure_data)
    resp = session.query(model.Measures).filter(model.Measures.id == 1).first()
    assert resp.liner == None
    assert resp.sampler == None

    NetworkCandidateGraph.update_from_jigsaw(session, '/Some/Path/To/An/ISISNetwork.cnet')
    resp = session.query(model.Measures).filter(model.Measures.id == 1).first()
    assert resp.liner == 0.1
    assert resp.sampler == 0.1