From 14f6c63f4b7a5f326512607dcbbbd2f9d4567e15 Mon Sep 17 00:00:00 2001 From: jsiefert Date: Thu, 9 Nov 2023 16:22:22 +0100 Subject: [PATCH 1/3] Add function get_sis2 --- shareloc/geomodels/los.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/shareloc/geomodels/los.py b/shareloc/geomodels/los.py index 4fa225e..68e2dd2 100644 --- a/shareloc/geomodels/los.py +++ b/shareloc/geomodels/los.py @@ -81,6 +81,7 @@ def los_creation(self, alt_min_max, fill_nan=False): out_crs = 4978 ecef_coord = coordinates_conversion(los_extrema, in_crs, out_crs) self.sis = ecef_coord[0::2, :] + self.sis2 = ecef_coord[1::2, :] vis = self.sis - ecef_coord[1::2, :] # /!\ normalized # @@ -99,6 +100,16 @@ def get_sis(self): """ return self.sis + def get_sis2(self): + """ + returns los bottom + TODO: not used. Use python property instead + + :return: sis2 + :rtype: numpy array + """ + return self.sis2 + def get_vis(self): """ returns los viewing vector From af129a970fad03c5d567916d1334dbc71015415c Mon Sep 17 00:00:00 2001 From: GUINET Jonathan Date: Wed, 15 Nov 2023 14:49:13 +0000 Subject: [PATCH 2/3] rework los --- shareloc/geomodels/los.py | 50 ++++++++++++++++++++++++------------- tests/geomodels/test_los.py | 28 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/shareloc/geomodels/los.py b/shareloc/geomodels/los.py index 68e2dd2..188e889 100644 --- a/shareloc/geomodels/los.py +++ b/shareloc/geomodels/los.py @@ -48,6 +48,10 @@ def __init__(self, sensor_positions, geometrical_model, alt_min_max=None, fill_n :type fill_nan : boolean """ + self._los_nb = None + self._sis = None # los starting point + self._vis = None # los viewing direction + self._eis = None # los ending point self.geometrical_model = geometrical_model self.sensors_positions = sensor_positions self.los_creation(alt_min_max, fill_nan) @@ -62,60 +66,70 @@ def los_creation(self, alt_min_max, fill_nan=False): :type fill_nan: boolean """ - self.los_nb = self.sensors_positions.shape[0] + self._los_nb = self.sensors_positions.shape[0] if alt_min_max is None: alt_min, alt_max = self.geometrical_model.get_alt_min_max() else: alt_min, alt_max = alt_min_max # LOS construction right - los_extrema = np.zeros([2 * self.los_nb, 3]) + los_extrema = np.zeros([2 * self._los_nb, 3]) list_col, list_row = (self.sensors_positions[:, 0], self.sensors_positions[:, 1]) - los_extrema[np.arange(0, 2 * self.los_nb, 2), :] = self.geometrical_model.direct_loc_h( + los_extrema[np.arange(0, 2 * self._los_nb, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_max, fill_nan ) - los_extrema[np.arange(1, 2 * self.los_nb, 2), :] = self.geometrical_model.direct_loc_h( + los_extrema[np.arange(1, 2 * self._los_nb, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_min, fill_nan ) in_crs = 4326 out_crs = 4978 ecef_coord = coordinates_conversion(los_extrema, in_crs, out_crs) - self.sis = ecef_coord[0::2, :] - self.sis2 = ecef_coord[1::2, :] - vis = self.sis - ecef_coord[1::2, :] + self._sis = ecef_coord[0::2, :] + self._eis = ecef_coord[1::2, :] + vis = self._sis - ecef_coord[1::2, :] # /!\ normalized # # direction vector creation vis_norm = np.linalg.norm(vis, axis=1) rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose() - self.vis = vis / rep_vis_norm + self._vis = vis / rep_vis_norm - def get_sis(self): + @property + def sis(self): """ returns los hat - TODO: not used. Use python property instead :return: sis :rtype: numpy array """ - return self.sis + return self._sis - def get_sis2(self): + @property + def eis(self): """ returns los bottom - TODO: not used. Use python property instead - :return: sis2 + :return: eis :rtype: numpy array """ - return self.sis2 + return self._eis - def get_vis(self): + @property + def vis(self): """ returns los viewing vector - TODO: not used. Use python property instead :return: vis :rtype: numpy array """ - return self.vis + return self._vis + + @property + def los_nb(self): + """ + returns los number + + :return: los_nb + :rtype: int + """ + return self._los_nb diff --git a/tests/geomodels/test_los.py b/tests/geomodels/test_los.py index 666a06b..efc3722 100644 --- a/tests/geomodels/test_los.py +++ b/tests/geomodels/test_los.py @@ -111,3 +111,31 @@ def test_compare_two_altitude(): assert (model_los.sis != wrong_los.sis).all assert (model_los.vis != wrong_los.vis).all + + +def test_los_properties(): + """ + test los properties + """ + + data_folder = data_path() + + # Load matches + matches = np.load(os.path.join(data_folder, "triangulation/matches-crop.npy")) + matches_left = matches[:, 0:2] + + # Load geometrical model + id_scene = "P1BP--2017092838284574CP" + file_dimap = os.path.join(data_folder, f"rpc/RPC_{id_scene}.XML") + geometrical_model = RPC.from_any(file_dimap) + + # Create los + model_los = LOS(matches_left, geometrical_model, [310, 850]) + assert np.allclose( + model_los.sis[0], np.array([4581872.88696028, 566896.05875082, 4387122.99450132]), rtol=0, atol=1e-8 + ) + assert np.allclose(model_los.vis[0], np.array([0.61688621, 0.00180051, 0.78705029]), rtol=0, atol=1e-8) + assert np.allclose( + model_los.eis[0], np.array([4581535.24740943, 566895.07328168, 4386692.2192622]), rtol=0, atol=1e-8 + ) + assert model_los.los_nb == 121 From cb46600031f000df51e5f2fc23a2849bf5680a1a Mon Sep 17 00:00:00 2001 From: GUINET Jonathan Date: Fri, 17 Nov 2023 14:07:27 +0000 Subject: [PATCH 3/3] interface --- shareloc/geofunctions/triangulation.py | 10 ++--- shareloc/geomodels/los.py | 48 ++++++++++++------------ tests/geofunctions/test_triangulation.py | 10 ++--- tests/geomodels/test_los.py | 22 +++++------ 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/shareloc/geofunctions/triangulation.py b/shareloc/geofunctions/triangulation.py index aef4fb5..075d765 100644 --- a/shareloc/geofunctions/triangulation.py +++ b/shareloc/geofunctions/triangulation.py @@ -92,7 +92,7 @@ def sensor_triangulation( def distance_point_los(los, points): """ distance between points and LOS - norm of cross prodcut between vector defined by LOS sis and point and LOS vis + norm of cross product between vector defined by LOS sis and point and LOS vis :param los: line of sight :type los: shareloc.los @@ -103,8 +103,8 @@ def distance_point_los(los, points): """ # norm(BA vect u)/norm(u) - vis = los.vis - vect_sis_p = points - los.sis + vis = los.viewing_vectors + vect_sis_p = points - los.starting_points dist = np.linalg.norm(np.cross(vect_sis_p, vis), axis=1) return dist @@ -120,10 +120,10 @@ def los_triangulation(left_los, right_los): :return: intersections in cartesian crs :rtype: numpy.array """ - vis = np.dstack((left_los.vis, right_los.vis)) + vis = np.dstack((left_los.viewing_vectors, right_los.viewing_vectors)) vis = np.swapaxes(vis, 1, 2) - sis = np.dstack((left_los.sis, right_los.sis)) + sis = np.dstack((left_los.starting_points, right_los.starting_points)) sis = np.swapaxes(sis, 1, 2) vivi = vis[..., :, np.newaxis] * vis[..., np.newaxis, :] diff --git a/shareloc/geomodels/los.py b/shareloc/geomodels/los.py index 188e889..07e5f84 100644 --- a/shareloc/geomodels/los.py +++ b/shareloc/geomodels/los.py @@ -48,10 +48,10 @@ def __init__(self, sensor_positions, geometrical_model, alt_min_max=None, fill_n :type fill_nan : boolean """ - self._los_nb = None - self._sis = None # los starting point - self._vis = None # los viewing direction - self._eis = None # los ending point + self._number = None + self._starting_points = None # los starting point + self._viewing_vectors = None # los viewing direction + self._ending_points = None # los ending point self.geometrical_model = geometrical_model self.sensors_positions = sensor_positions self.los_creation(alt_min_max, fill_nan) @@ -66,70 +66,68 @@ def los_creation(self, alt_min_max, fill_nan=False): :type fill_nan: boolean """ - self._los_nb = self.sensors_positions.shape[0] + self._number = self.sensors_positions.shape[0] if alt_min_max is None: alt_min, alt_max = self.geometrical_model.get_alt_min_max() else: alt_min, alt_max = alt_min_max # LOS construction right - los_extrema = np.zeros([2 * self._los_nb, 3]) + los_extrema = np.zeros([2 * self._number, 3]) list_col, list_row = (self.sensors_positions[:, 0], self.sensors_positions[:, 1]) - los_extrema[np.arange(0, 2 * self._los_nb, 2), :] = self.geometrical_model.direct_loc_h( + los_extrema[np.arange(0, 2 * self._number, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_max, fill_nan ) - los_extrema[np.arange(1, 2 * self._los_nb, 2), :] = self.geometrical_model.direct_loc_h( + los_extrema[np.arange(1, 2 * self._number, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_min, fill_nan ) in_crs = 4326 out_crs = 4978 ecef_coord = coordinates_conversion(los_extrema, in_crs, out_crs) - self._sis = ecef_coord[0::2, :] - self._eis = ecef_coord[1::2, :] - vis = self._sis - ecef_coord[1::2, :] + self._starting_points = ecef_coord[0::2, :] + self._ending_points = ecef_coord[1::2, :] + vis = self._starting_points - ecef_coord[1::2, :] # /!\ normalized # # direction vector creation vis_norm = np.linalg.norm(vis, axis=1) rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose() - self._vis = vis / rep_vis_norm + self._viewing_vectors = vis / rep_vis_norm @property - def sis(self): + def starting_points(self) -> np.ndarray: """ returns los hat :return: sis - :rtype: numpy array """ - return self._sis + return self._starting_points @property - def eis(self): + def ending_points(self) -> np.ndarray: """ returns los bottom :return: eis :rtype: numpy array """ - return self._eis + return self._ending_points @property - def vis(self): + def viewing_vectors(self): """ - returns los viewing vector + returns los viewing vectors :return: vis - :rtype: numpy array + """ - return self._vis + return self._viewing_vectors @property - def los_nb(self): + def number(self) -> int: """ returns los number - :return: los_nb - :rtype: int + :return: number """ - return self._los_nb + return self._number diff --git a/tests/geofunctions/test_triangulation.py b/tests/geofunctions/test_triangulation.py index 6772a53..2b6cc2b 100644 --- a/tests/geofunctions/test_triangulation.py +++ b/tests/geofunctions/test_triangulation.py @@ -101,25 +101,25 @@ class SimulatedLOS: """line of sight class""" def __init__(self): - self.sis = np.array([[100.0, 10.0, 200.0], [100.0, 10.0, 200.0]]) - self.vis = np.array([[0.0, 1.0, 0.0], [0.0, 1.0, 0.0]]) + self.starting_points = np.array([[100.0, 10.0, 200.0], [100.0, 10.0, 200.0]]) + self.viewing_vectors = np.array([[0.0, 1.0, 0.0], [0.0, 1.0, 0.0]]) def print_sis(self): """ print los hat """ - print(self.sis) + print(self.starting_points) def print_vis(self): """ print los viewing vector """ - print(self.vis) + print(self.viewing_vectors) los = SimulatedLOS() distance = 10.0 - point = los.sis + 100.0 * los.vis + distance * np.array([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]) + point = los.starting_points + 100.0 * los.viewing_vectors + distance * np.array([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]) residue = distance_point_los(los, point) assert distance == pytest.approx(residue, abs=1e-9) diff --git a/tests/geomodels/test_los.py b/tests/geomodels/test_los.py index efc3722..733b1f5 100644 --- a/tests/geomodels/test_los.py +++ b/tests/geomodels/test_los.py @@ -83,9 +83,9 @@ def test_los_creation_with_different_alt(alt): rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose() vis_gt = vis_gt / rep_vis_norm - assert left_los.los_nb == los_nb_gt - assert (left_los.sis == sis_gt).all - assert (left_los.vis == vis_gt).all + assert left_los.number == los_nb_gt + assert (left_los.starting_points == sis_gt).all + assert (left_los.viewing_vectors == vis_gt).all def test_compare_two_altitude(): @@ -109,13 +109,13 @@ def test_compare_two_altitude(): model_los = LOS(matches_left, geometrical_model, [310, 850]) wrong_los = LOS(matches_left, geometrical_model, [0, 210]) - assert (model_los.sis != wrong_los.sis).all - assert (model_los.vis != wrong_los.vis).all + assert (model_los.starting_points != wrong_los.starting_points).all + assert (model_los.viewing_vectors != wrong_los.viewing_vectors).all -def test_los_properties(): +def test_los_parameters(): """ - test los properties + test los parameters """ data_folder = data_path() @@ -132,10 +132,10 @@ def test_los_properties(): # Create los model_los = LOS(matches_left, geometrical_model, [310, 850]) assert np.allclose( - model_los.sis[0], np.array([4581872.88696028, 566896.05875082, 4387122.99450132]), rtol=0, atol=1e-8 + model_los.starting_points[0], np.array([4581872.88696028, 566896.05875082, 4387122.99450132]), rtol=0, atol=1e-8 ) - assert np.allclose(model_los.vis[0], np.array([0.61688621, 0.00180051, 0.78705029]), rtol=0, atol=1e-8) + assert np.allclose(model_los.viewing_vectors[0], np.array([0.61688621, 0.00180051, 0.78705029]), rtol=0, atol=1e-8) assert np.allclose( - model_los.eis[0], np.array([4581535.24740943, 566895.07328168, 4386692.2192622]), rtol=0, atol=1e-8 + model_los.ending_points[0], np.array([4581535.24740943, 566895.07328168, 4386692.2192622]), rtol=0, atol=1e-8 ) - assert model_los.los_nb == 121 + assert model_los.number == 121