Commit e0d7c2d3 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Adding propagation path identifier hashing and difference function for two lists

parent 408b5c8b
%% General
% Load and generate ids
pps = ita_propagation_load_paths( 'ppa_example_paths.json' );
fprintf( 'Found %i paths\n', numel( pps ) );
[ pps_with_ids, pps_hash_table ] = ita_propagation_paths_add_identifiers( pps, true ); % verbose mode
% Compare
pps_2 = ita_propagation_load_paths( 'ppa_example_paths_2.json' );
[ pps_2, pps_hash_table_2 ] = ita_propagation_paths_add_identifiers( pps_2 );
[ pps_new, pps_del, pps_alt ] = ita_propagation_paths_diff( pps_with_ids, pps_2 );
function [ pps_with_ids, pps_hash_table ] = ita_propagation_paths_add_identifiers( pps, verbose_hashing )
%
% ita_propagation_paths_add_identifiers Adds identifiers to the propagation
% paths struct based on a hashing convention that takes surface and edge
% ids into account.
%%
% Example: pps_with_ids = ita_propagation_paths_add_identifiers( pps )
% [ pps_with_ids, pps_hash_table ] = ita_propagation_paths_add_identifiers( pps, true ) % verbose output
%
if nargin < 2
verbose_hashing = false;
end
if ~isfield( pps, 'class' )
error( 'Could not modify propagation path list, struct is missing field "class"' )
end
if ~isfield( pps, 'propagation_anchors' )
error( 'Could not modify propagation path list, struct is missing field "propagation_anchors"' )
end
pps_with_ids = pps;
pps_hash_table = struct();
for n = 1:numel( pps )
pp = pps( n );
path_id_clear = '';
for a = 1:numel( pp.propagation_anchors )
anchor = pp.propagation_anchors{ a };
switch anchor.anchor_type
case { 'source', 'emitter' }
anchor_id_seg = strcat( 'S-', anchor.name );
case { 'receiver', 'sensor' }
anchor_id_seg = strcat( 'R-', anchor.name );
case 'specular_reflection'
anchor_id_seg = sprintf( 'SR-%i-%i', a-1, anchor.polygon_id );
case { 'outer_edge_diffraction', 'inner_edge_diffraction' }
anchor_id_seg = sprintf( 'ED-%i-%i-%i', a-1, anchor.main_wedge_face_id, anchor.opposite_wedge_face_id );
end
if a == 1
path_id_clear = strcat( path_id_clear, anchor_id_seg );
else
path_id_clear = strcat( path_id_clear, '_', anchor_id_seg );
end
end
path_id_hashed = mlreportgen.utils.hash( path_id_clear );
% store in output variables
pps_with_ids( n ).identifier = path_id_hashed;
pps_hash_table( n ).key = path_id_clear;
pps_hash_table( n ).hash = path_id_hashed;
if verbose_hashing
fprintf( '%s <= %s\n', path_id_hashed, path_id_clear )
end
end
end
function [ pps_new, pps_del, pps_common ] = ita_propagation_paths_diff( pps_1, pps_2 )
%
% ita_propagation_paths_diff Returns difference information on two
% propagation path lists
%%
% Example: [ pps_new, pps_del, pps_alt ] = ita_propagation_paths_diff( pps_1, pps_2 )
%
% Note: no common propagation paths are found if the identifier is empty!
% Path lists with non-unique identifiers may lead to unintended results.
%
%
if ~isfield( pps_1, 'class' ) || ~isfield( pps_2, 'class' )
error( 'Could not diff propagation path lists, struct is missing field "class"' )
end
if ~isfield( pps_1, 'propagation_anchors' ) || ~isfield( pps_2, 'propagation_anchors' )
error( 'Could not diff propagation path lists, struct is missing field "propagation_anchors"' )
end
% terribly slow search algorithm comes here:
missing_in_1 = ones( numel( pps_2 ), 1 );
missing_in_2 = ones( numel( pps_1 ), 1 );
found_in_both = zeros( numel( pps_1 ), 1 );
for n1 = 1:numel( pps_1 )
for n2 = 1:numel( pps_2 )
if strcmpi( pps_1( n1 ).identifier, pps_2( n2 ).identifier ) && ~isempty( pps_1( n1 ).identifier )
found_in_both( n1 ) = 1;
missing_in_1( n2 ) = 0;
missing_in_2( n1 ) = 0;
end
end
end
pps_new = pps_2( missing_in_1 == 1 );
pps_del = pps_1( missing_in_2 == 1 );
pps_common = pps_1( found_in_both == 1 );
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment