From 9b44e4859fc1883676866afa4ffc014731d632d0 Mon Sep 17 00:00:00 2001 From: Lionel GUEZ <guez@lmd.ens.fr> Date: Thu, 5 Oct 2023 21:42:20 +0200 Subject: [PATCH] Give special treatment to phantom patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is case 2 correction in the Matlab program of Rémi Laxenaire. --- Trajectories/trajectories.py | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Trajectories/trajectories.py b/Trajectories/trajectories.py index 0ed32247..252a31c2 100755 --- a/Trajectories/trajectories.py +++ b/Trajectories/trajectories.py @@ -16,6 +16,8 @@ import graph_tool from graph_tool import topology import json import sys +import report_graph +import numpy as np def new_traj(ind_traj, traj_prop, n, traj_vert_ind): """Assign new trajectory to vertex index n.""" @@ -61,6 +63,55 @@ traj_vert_ind = [] # of vertex indices. for n in topology.topological_sort(g): + # First, we check whether we have a phantom pattern. Phantom + # eddies may appear in altimetric data because of + # interpolation. In a phantom pattern, we have splitting + # immediately followed by merging. We do not want to let phantom + # patterns interrupt trajectories. + + if g.vertex(n).in_degree() == 2: + pred = g.get_in_neighbors(n) + + if np.all(g.get_in_degrees(pred) == 1) \ + and np.all(g.get_out_degrees(pred) == 1): + n1 = g.get_in_neighbors(pred[0])[0] + n2 = g.get_in_neighbors(pred[1])[0] + + if n1 == n2 and g.vertex(n1).out_degree() == 2: + # We have a splitting event at n1 immediately followed + # by a merging at n. Check the time interval between + # splitting and merging. The date of merging is the + # date of the first eddy in segment n and the date of + # splitting is the date of the last eddy in segment + # n1. + date_merging = report_graph.node_to_date_eddy( + g.vp.name[n], g.gp.e_overestim, only_date = True) + date_splitting = report_graph.node_to_date_eddy( + g.vp.inst_eddies[n1][- 1], g.gp.e_overestim, + only_date = True) + + if date_merging - date_splitting <= 6: + # We have a phantom pattern. Get the vertex on the + # side of the shortest path: + v_short = topology.shortest_path( + g, n1, n, weights = g.ep.cost_function, + dag = True)[0][1] + + if traj_prop[v_short] != traj_prop[n1]: + # Correct the trajectories that were assigned + # according to closest successor, that is: + # swap the trajectories of pred[0] and + # pred[1]: + traj_prop[pred[0]], traj_prop[pred[1]] \ + = traj_prop[pred[1]], traj_prop[pred[0]] + traj_vert_ind[traj_prop[pred[0]]][- 1], \ + traj_vert_ind[traj_prop[pred[1]]][- 1] \ + = traj_vert_ind[traj_prop[pred[1]]][- 1], \ + traj_vert_ind[traj_prop[pred[0]]][- 1] + + traj_prop[n] = traj_prop[n1] + traj_vert_ind[traj_prop[n1]].append(n) + if traj_prop[n] == - 1: if g.vertex(n).in_degree() >= 1: # Find the index of the closest direct predecessor of a node: -- GitLab