NORCE Logo

Ambiguity Correction

In the following we present the phase-cycle ambiguity correction in InSAR time series, used to reduce false seasonal jumps introduced by long winter acquisition gaps. The proposed method detects suspicious season-to-season slope inconsistencies and applies a conservative cycle-shift correction only when the expected continuity improves enough.

For this analysis, we build a stratified subset across mean-velocity quantiles so diagnostics include low/near-zero/high motion regimes. In particular, we create 5 groups of time series, each one associated with different quantiles of the mean velocity distribution.

Distribution of mean velocities for the selected subset of time series.
Distribution of mean velocities for the selected subset of time series.

Step 1: Season segmentation

We identify the large temporal gaps that define the season boundaries:

\[\Delta t_j = t_{j+1} - t_j,\qquad \text{boundary if } \Delta t_j > \tau_{\text{gap}}\]

where:

Automatic detection of seasonal gaps in the time series.
Automatic detection of seasonal gaps in the time series.

Step 2: Multi-year trend slope fit

For each series $i$, fit robust trend line with RANSAC (a linear fitting technique robust to outliers):

\[\hat{x}_i(t) = a_i t + b_i\]

where:

Below, we plot the RANSAC fit vs observed time series (one sample per each of the mean-velocity subgroups):

\[\hat{x}_{i_g}(t_j) = a_{i_g} t_j + b_{i_g}\]

where:

RANSAC fit vs observed time series (one sample per each of the mean-velocity subgroups).
RANSAC fit vs observed time series (one sample per each of the mean-velocity subgroups).

Step 3: Per-season slope on trimmed season windows

We estimate a stable seasonal slope $\beta_{i,s}$ for each season $s$ in each series $i$, while reducing the influence of noisy points at season boundaries. We do the fit on a trimmed subset $S_s^{trim}$ of the dat asamples. This is done because the first/last points of a season are often less reliable (e.g., snow-transition periods, seasonal filtering artifacts, edge effects after long gaps). Using $S_s^{trim}$ instead of full $S_s$ makes the seasonal slope estimate less sensitive to those boundary outliers, improving robustness of the later ambiguity decision steps.

Let $m_{trim}$ be the number of points to remove from each season edge.

The per-series/per-season slope is computed as:

\[\beta_{i,s} = \frac{\sum_{u \in S_s^{trim}}(x_{i,u}-\bar{x}_{i,s})(t_u-\bar{t}_s)} {\sum_{u \in S_s^{trim}}(t_u-\bar{t}_s)^2}\]

where:

Also:

\[\bar{x}_{i,s} = \frac{1}{\vert S_{s}^{trim}\vert}\sum_{u\in S_{s}^{trim}} x_{i,u}\]

and

\[\bar{t}_{s} = \frac{1}{\vert S_{s}^{trim}\vert}\sum_{u\in S_{s}^{trim}} t_u\]

Note: $\beta_{i,s}$ has units displacement/day.

Step 4: Compute anomaly signals

We compute the seasonal slope deviation from trend for series $i$ in season $s$ as:

\[r_{i,s} = \beta_{i,s} - a_i\]

The boundary jump between season $s-1$ and $s$ is defined as:

\[j_{i,s} = \left| \operatorname{median}\left(\{x_{i,u}:u\in W_{s-1}^{tail}\}\right) - \operatorname{median}\left(\{x_{i,u}:u\in W_s^{head}\}\right) \right|\]

where:

Step 5: Normalized scores and suspicious gate

We now compute robust z-scores using median and MAD (median absolute deviation).

Rate robust z-score:

\[z^{rate}_{i,s} = \frac{r_{i,s} - \operatorname{median}_{s'}(r_{i,s'})} {1.4826\,\operatorname{median}_{s'}\left|r_{i,s'}-\operatorname{median}_{s''}(r_{i,s''})\right|+\epsilon}\]

Boundary robust z-score:

\[z^{jump}_{i,s} = \frac{j_{i,s} - \operatorname{median}_{s'}(j_{i,s'})} {1.4826\,\operatorname{median}_{s'}\left|j_{i,s'}-\operatorname{median}_{s''}(j_{i,s''})\right|+\epsilon}\]

Suspicious gate:

\[\text{suspicious}_{i,s} = \left(|z^{rate}_{i,s}| \ge \tau_{rate}\right) \land \left(z^{jump}_{i,s} \ge \tau_{jump}\right)\]

where:

Distribution of $z^{rate}_{i,s}$ and $z^{jump}_{i,s}$.
Distribution of $z^{rate}_{i,s}$ and $z^{jump}_{i,s}$.

Step 6: Candidate cycle correction, confidence, and apply gate

Turn a suspicious season into an actual correction decision.

6.1 Convert cycle rate to day units

\[c_d = \frac{\texttt{cycle_rate_mm_per_year}}{365.25}\]

where:

6.2 Choose discrete candidate shift

For each series $i$ and season $s$, we compute:

\[k^{raw}_{i,s} = \frac{r_{i,s}}{c_d}\]

$k^{raw}_ {i,s}$ is the estimated number of cycle-rate units needed to explain the seasonal deviation $r_{i,s}$.
For example, $k^{raw}_ {i,s}\approx 1.8$ means the deviation is close to two cycle units; $k^{raw}_ {i,s}\approx 0$ means no cycle-shift correction is indicated.

Then snap to the nearest integer candidate in $\mathcal{K}$:

\[k^*_{i,s} = \arg\min_{k\in\mathcal{K}}\left|k^{raw}_{i,s} - k\right|\]

where $\mathcal{K}$ is the set of candidates (default ${ -2,-1,0,1,2 }$).

6.3 Score improvement and confidence

Residual without correction:

\[d^{(0)}_{i,s} = |r_{i,s}|\]

Residual with candidate correction:

\[d^{(k)}_{i,s} = |r_{i,s} - k^*_{i,s} c_d|\]

Relative improvement:

\[\text{improvement}_{i,s} = \frac{d^{(0)}_{i,s} - d^{(k)}_{i,s}}{d^{(0)}_{i,s} + \epsilon}\]

Interpretation of $\text{improvement}_{i,s}$:

Range of improvement $\text{improvement}_{i,s}$:

To control the range, we define $\text{confidence}^{raw}_{i,s} \in [0,1]$:

\[\text{confidence}^{raw}_{i,s} = \operatorname{clip}(\text{improvement}_{i,s}, 0, 1)\]

6.4 Neighbor safety penalty (optional)

This step reduces confidence when the local neighborhood shows a coherent suspicious pattern with the same sign, to avoid over-correcting regional signals.

Let $\mathcal{N}_i$ be the $K_n$ nearest neighbors of series $i$, and let $\mathbf{1}[\cdot]$ be the indicator function.

Neighbor coherence is computed as:

\[\text{neighbor_coherence}_{i,s} = \frac{1}{K_n}\sum_{n\in\mathcal{N}_i} \mathbf{1}\!\left(\text{suspicious}_{n,s}=1\;\land\;\operatorname{sign}(r_{n,s})=\operatorname{sign}(r_{i,s})\right)\]

Gating condition:

\[\text{penalty_mask}_{i,s} = \left(\text{neighbor_coherence}_{i,s} \ge \tau_{neigh}\right)\]

with:

Applied confidence update:

\[\text{confidence}_{i,s}= \begin{cases} \text{confidence}^{raw}_{i,s}(1-\lambda), & \text{if } \text{neighbor_coherence}_{i,s} \ge \tau_{neigh} \\ \text{confidence}^{raw}_{i,s}, & \text{otherwise} \end{cases}\]

6.5 Final apply gate

A correction is applied only if all conditions are true:

\[\text{apply}_{i,s} = \text{suspicious}_{i,s} \land (k^*_{i,s} \neq 0) \land (\text{improvement}_{i,s} \ge \tau_{imp}) \land (\text{confidence}_{i,s} \ge \tau_{conf})\]

with:

6.6 Apply correction as seasonal ramp

For each selected series and season, correction is applied to all timestamps in that season:

\[x^{corr}_{i,t} = x_{i,t} - k^*_{i,s} c_d (t - t_{s,0}), \quad t\in s\]

Visualization of corrected time series

From each median-velocity group, we visualize the original displacement series $x_{orig}(t)$ (gray line) and the corrected displacement series $x_{corr}(t)$ (blue line). The orange spans represent the seasons where correction was applied.

Corrected time series. One sample with high confidence from each representative group is reported.
Corrected time series. One sample with high confidence from each representative group is reported.

List of hyperparameters

Name Description
$\tau_{gap}$ season-gap threshold
$\tau_{rate}$ robust rate-z threshold
$\tau_{jump}$ robust jump-z threshold
$\tau_{imp}$ minimum improvement threshold
$\tau_{conf}$ minimum confidence threshold
$\tau_{neigh}$ neighbor-coherence threshold
$m_{trim}$ edge-trim points per season
$w_{jump}$ boundary window size
$c_{yr}$ cycle rate in mm/year
$\mathcal{K}$ candidate cycle-shift set
$K_n$ number of spatial neighbors
$\lambda_{neigh}$ neighbor penalty factor