Pairs and Loops#

class faninsar.Pair(pair: Sequence[datetime, datetime])#

Bases: object

Pair class for one pair.

__init__(pair: Sequence[datetime, datetime]) None#
Parameters:

pair (Sequence) – Sequence object of two dates. Each date is a datetime object. For example, (date1, date2).

property values: ndarray[tuple[int, ...], dtype[datetime64]]#

the values of the pair with format of datetime.

property name: str#

String of the pair with format of ‘%Y%m%d_%Y%m%d’.

property days: int#

the time span of the pair in days.

property primary: datetime64#

the primary dates of all pairs

property secondary: datetime64#

the secondary dates of all pairs

primary_string(date_format='%Y%m%d') str#

return the primary dates of all pairs in string format

Parameters:

date_format (str) – Format of the date string. Default is ‘%Y%m%d’. See more at strftime Format Codes.

secondary_string(date_format='%Y%m%d') str#

return the secondary dates of all pairs in string format

Parameters:

date_format (str) –

Format of the date string. Default is ‘%Y%m%d’. See more at strftime Format Codes.

classmethod from_name(name: str, parse_function: Callable | None = None, date_args: dict = {}) Pair#

initialize the pair class from a pair name

Parameters:
  • name (str) – Pair name.

  • parse_function (Callable, optional) – Function to parse the date strings from the pair name. If None, the pair name will be split by ‘_’ and the last 2 items will be used. Default is None.

  • date_args (dict, optional) – Keyword arguments for pd.to_datetime() to convert the date strings to datetime objects. For example, {‘format’: ‘%Y%m%d’}. Default is {}.

Returns:

pair – Pair class.

Return type:

Pair

class faninsar.Pairs(pairs: Sequence[Sequence[datetime, datetime]] | Sequence[Pair], sort: bool = True)#

Bases: object

Pairs class to handle pairs

Examples

prepare dates and pairs for examples:

>>> dates = pd.date_range('20130101', '20231231').values
>>> n = len(dates)
>>> pair_ls = []
>>> loop_ls = []
>>> for i in range(5):
...    np.random.seed(i)
...    pair_ls.append(dates[np.random.randint(0, n, 2)])

initialize pairs from a list of pairs

>>> pairs = Pairs(pair_ls)
>>> print(pairs)
    primary  secondary
0 2013-06-24 2016-02-21
1 2013-08-24 2015-11-28
2 2017-08-16 2018-03-14
3 2020-01-20 2021-11-15
4 2020-02-21 2020-06-25

select pairs by date slice

>>> pairs1 = pairs['2018-03-09':]
>>> print(pairs1)
    primary  secondary
0 2020-01-20 2021-11-15
1 2020-02-21 2020-06-25

pairs can be added (union) and subtracted (difference)

>>> pairs2 = pairs - pairs1
>>> pairs3 = pairs1 + pairs2
>>> print(pairs2)
    primary  secondary
0 2013-06-24 2016-02-21
1 2013-08-24 2015-11-28
2 2017-08-16 2018-03-14
>>> print(pairs3)
    primary  secondary
0 2013-06-24 2016-02-21
1 2013-08-24 2015-11-28
2 2017-08-16 2018-03-14
3 2020-01-20 2021-11-15
4 2020-02-21 2020-06-25

pairs can be compared with ==`and `!=

>>> print(pairs3 == pairs)
>>> print(pairs3 != pairs)
True
False
__init__(pairs: Sequence[Sequence[datetime, datetime]] | Sequence[Pair], sort: bool = True) None#

initialize the pairs class

Parameters:
  • pairs (Sequence) – Sequence object of pairs. Each pair is an Sequence or Pair object of two dates with format of datetime. For example, [(date1, date2), …].

  • sort (bool, optional) – Whether to sort the pairs. Default is True.

property values: ndarray[tuple[int, ...], dtype[datetime64]]#

return the numpy array of the pairs

property names: ndarray[tuple[int, ...], dtype[str_]]#

return the names (string format) of the pairs

property dates: DatetimeIndex#

return the sorted dates array of all pairs in type of np.datetime64[D]

property days: ndarray[tuple[int, ...], dtype[int64]]#

return the time span of all pairs in days

property primary: DatetimeIndex#

return the primary dates of all pairs

property secondary: DatetimeIndex#

return the secondary dates of all pairs

primary_string(date_format='%Y%m%d') Index#

return the primary dates of all pairs in string format

Parameters:

date_format (str) –

Format of the date string. Default is ‘%Y%m%d’. See more at strftime Format Codes.

secondary_string(date_format='%Y%m%d') Index#

return the secondary dates of all pairs in string format

Parameters:

date_format (str) –

Format of the date string. Default is ‘%Y%m%d’. See more at strftime Format Codes.

property edge_index: ndarray[tuple[int, ...], dtype[int64]]#

return the index of the pairs in the dates coordinate (edge index in graph theory)

property shape: tuple[int, int]#

return the shape of the pairs array

classmethod from_names(names: Sequence[str], parse_function: Callable | None = None, date_args: dict = {}) Pairs#

initialize the pair class from a pair name

Note

The pairs will be in the order of the input names. If you want to sort the pairs, you can call the Pairs.sort() method to achieve it.

Parameters:
  • name (str) – Pair name.

  • parse_function (Callable, optional) – Function to parse the date strings from the pair name. If None, the pair name will be split by ‘_’ and the last 2 items will be used. Default is None.

  • date_args (dict, optional) – Keyword arguments for pd.to_datetime() to convert the date strings to datetime objects. For example, {‘format’: ‘%Y%m%d’}. Default is {}.

Returns:

pairs – unsorted Pairs object.

Return type:

Pairs

where(pairs: list[str] | list[Pair] | 'Pairs', return_type: Literal['index', 'mask'] = 'index') NDArray[np.int64 | np.bool_] | None#

return the index of the pairs

Parameters:
  • pairs (list of str or Pair, or Pairs) – Pair names or Pair objects, or Pairs object.

  • return_type (str, optional) – Whether to return the index or mask of the pairs. Default is ‘index’.

intersect(pairs: list[str] | list[Pair] | 'Pairs') 'Pairs' | None#

return the intersection of the pairs. The pairs both in self and input pairs.

Parameters:

pairs (list of str or Pair, or Pairs) – Pair names or Pair objects, or Pairs object.

union(pairs: list[str] | list[Pair] | 'Pairs') Pairs#

return the union of the pairs. All pairs that in self and input pairs. A more robust operation than addition.

Parameters:

pairs (list of str or Pair, or Pairs) – Pair names or Pair objects, or Pairs object.

difference(pairs: list[str] | list[Pair] | 'Pairs') 'Pairs' | None#

return the difference of the pairs. The pairs in self but not in pairs. A more robust operation than subtraction.

Parameters:

pairs (list of str or Pair, or Pairs) – Pair names or Pair objects, or Pairs object.

copy() Pairs#

return a copy of the pairs

sort(order: list | Literal['pairs', 'primary', 'secondary', 'days'] = 'pairs', ascending: bool = True, inplace: bool = True) tuple[Pairs, ndarray[tuple[int, ...], dtype[int64]]] | None#

sort the pairs

Parameters:
  • order (str or list of str, optional) –

    By which fields to sort the pairs. This argument specifies which fields to compare first, second, etc. Default is ‘pairs’.

    The available options are one or a list of: [‘pairs’, ‘primary’, ‘secondary’, ‘days’].

  • ascending (bool, optional) – Whether to sort ascending. Default is True.

  • inplace (bool, optional) – Whether to sort the pairs inplace. Default is True.

Returns:

  • None or (Pairs, np.ndarray). if inplace is True, return the sorted pairs

  • and the index of the sorted pairs in the original pairs. Otherwise,

  • return None.

to_names(prefix: str | None = None) ndarray[tuple[int, ...], dtype[str_]]#

generate pairs names string with prefix

Parameters:

prefix (str) – Prefix of the pair file names. Default is None.

Returns:

names – Pairs names string with format of ‘%Y%m%d_%Y%m%d’.

Return type:

np.ndarray

to_frame() DataFrame#

return the pairs as a DataFrame

to_triplet_loops() TripletLoops#

return all possible triplet loops from the pairs

to_loops(max_acquisition: int = 5, max_days: int | None = None, edge_pairs: 'Pairs' | None = None, edge_days: int | None = None) Loops#

Return all possible loops from the pairs.

Important

The pairs in the loops may be fewer than the input pairs. You can use the Pairs.where() method to get the index/mask of the pairs in the loops from the input pairs.

Example:

>>> loops = pairs.to_loops()
>>> mask = pairs.where(loops.pairs, return_type='mask')
Parameters:
  • max_acquisition (int) –

    The maximum number of acquisitions in the loops. It should be at least 3.

    Note

    The number of acquisitions is equal to the number of intervals + 1 \(n (acquisition) = n (edge\ pairs) + 1 (diagonal\ pair) = n (intervals) + 1\).

  • max_days (int, optional) – The maximum number of days for the pairs in the loops. If None, all available pairs will be used. Default is None.

  • edge_pairs (Pairs, optional) – The edge pairs to form loops. If None, edge_days must be provided.

  • edge_days (int, optional) –

    The maximum number of days used to identify the edge pairs. If None, edge_pairs must be provided. Default is None.

    Note

    This parameter will be ignored if edge_pairs is provided.

to_matrix(dtype=None) ndarray[tuple[int, ...], dtype[number]]#

return the SBAS matrix

Parameters:

matrix (np.ndarray) – SBAS matrix in shape of (n_pairs, n_dates-1). The dates between pairs are set to 1, otherwise 0.

class faninsar.Loop(loop: Sequence[datetime])#

Bases: object

Loop class containing multiple pairs/acquisitions.

__init__(loop: Sequence[datetime]) None#

Initialize the Loop class

loop: Sequence

Sequence object of dates. Each date is a datetime object. For example, (date1, …, date_n).

property values: ndarray[tuple[int, ...], dtype[datetime64]]#

return the values array of the loop.

Returns:

values – dates of the loop with format of np.datetime64[D].

Return type:

np.ndarray

property pairs: Pairs#

all pairs of the loop.

property name: str#

the string format the loop.

Returns:

name – String of the loop.

Return type:

str

from_name(name: str, parse_function: Callable | None = None, date_args: dict = {}) Loop#

initialize the loop class from a loop name

Parameters:
  • name (str) – Loop name.

  • parse_function (Callable, optional) – Function to parse the date strings from the loop name. If None, the loop name will be split by ‘_’ and the last 3 items will be used. Default is None.

  • date_args (dict, optional) – Keyword arguments for pd.to_datetime() to convert the date strings to datetime objects. For example, {‘format’: ‘%Y%m%d’}. Default is None.

Returns:

loop – Loop object.

Return type:

Loop

class faninsar.Loops(loops: list, sort=True)#

Bases: object

Loops class to handle loops with multiple acquisitions.

__init__(loops: list, sort=True) None#

initialize the loops class

Parameters:
  • loops (list) – a list containing Loop objects.

  • sort (bool, optional) – Whether to sort the loops. Default is True.

property loops: ndarray[tuple[int, ...], dtype[object_]]#

the loops in the numpy array format.

property shape: tuple[int, int]#

the shape of the loops array with format of (n_loops, n_pairs).

property names: ndarray[tuple[int, ...], dtype[str_]]#

the names (str format) of the loops.

property pairs: Pairs#

all pairs in the loops.

property edge_pairs: Pairs#

all edge pairs in the loops.

property diagonal_pairs: Pairs#

all diagonal pairs in the loops.

sort(ascending: bool = True, inplace: bool = True) 'Loops' | None#

sort the loops

Parameters:
  • ascending (bool, optional) – Whether to sort the loops ascending. Default is True.

  • inplace (bool, optional) – Whether to sort the loops in place. if False, return the sorted loops. Default is True.

to_matrix(dtype=None) ndarray[tuple[int, ...], dtype[number]]#

return a design matrix which rows and columns are loops and pairs respectively. The values of the matrix are 1 for the edge pairs, -1 for the diagonal pairs, and 0 otherwise.

class faninsar.TripletLoops(loops: Sequence[Sequence[datetime, datetime, datetime]] | Sequence[TripletLoop], sort: bool = True)#

Bases: object

TripletLoops class to handle loops with three pairs/acquisitions.

__init__(loops: Sequence[Sequence[datetime, datetime, datetime]] | Sequence[TripletLoop], sort: bool = True) None#

initialize the triplet loops class

Parameters:

loops (Sequence) – Sequence object of triplet loops. Each loop is an Sequence object of three dates with format of datetime or TripletLoop object. For example, [(date1, date2, date3), …].

property values: ndarray[tuple[int, ...], dtype[datetime64]]#

return the values of the loops.

Returns:

values – Values of the loops with format of datetime.

Return type:

np.ndarray

property names: ndarray[tuple[int, ...], dtype[str_]]#

the names (sting format) of the loops.

property dates: ndarray[tuple[int, ...], dtype[datetime64]]#

Sorted dates of the loops with format of datetime.

property shape: tuple[int, int]#

the shape of the loop array

property pairs: Pairs#

all sorted pairs of the loops.

property pairs12: Pairs#

the first pairs of the loops.

property pairs23: Pairs#

the second pairs of the loops.

property pairs13: Pairs#

the third pairs of the loops.

property days12: ndarray[tuple[int, ...], dtype[int64]]#

the time span of the first pair in days.

property days23: ndarray[tuple[int, ...], dtype[int64]]#

the time span of the second pair in days.

property days13: ndarray[tuple[int, ...], dtype[int64]]#

the time span of the third pair in days.

property index: ndarray[tuple[int, ...], dtype[int64]]#

the index of the loops in dates coordinates.

classmethod from_names(names: list[str], parse_function: Callable | None = None, date_args: dict = {}) TripletLoops#

initialize the loops class from a list of loop file names.

Parameters:
  • names (list) – list of loop file names.

  • parse_function (Callable, optional) – Function to parse the date strings from the loop file name. If None, the loop file name will be split by ‘_’ and the last 3 items will be used. Default is None.

  • date_args (dict, optional) – Keyword arguments for pd.to_datetime() to convert the date strings to datetime objects. For example, {‘format’: ‘%Y%m%d’}. Default is {}.

Returns:

loops – unsorted TripletLoops object.

Return type:

TripletLoops

to_names(prefix: str | None = None) ndarray[tuple[int, ...], dtype[str_]]#

return the string name of each loop.

Parameters:

prefix (str, optional) – Prefix of the output loop names. Default is None.

Returns:

names – String names of the loops.

Return type:

np.ndarray

to_frame(target: Literal['pairs', 'dates'] = 'pairs') DataFrame#

return the loops as a DataFrame

Parameters:

target (str, one of ['pairs', 'dates']) – Target of the DataFrame. Default is ‘pairs’.

to_matrix() ndarray[tuple[int, ...], dtype[int8]]#

return loop matrix (containing 1, -1, 0) from pairs.

Returns:

matrix – TripletLoop matrix with the shape of (n_loop, n_pair). The values of each loop/row in matrix are:

  • 1: pair12 and pair23

  • -1: pair13

  • 0: otherwise

Return type:

np.ndarray

where(loop: str | TripletLoop, return_type: Literal['index', 'mask'] = 'index') int | None#

return the index of the loop

Parameters:
  • loop (str or TripletLoop) – TripletLoop name or TripletLoop object.

  • return_type (str, optional) – Whether to return the index or mask of the loop. Default is ‘index’.

sort(order: str | list = 'pairs', ascending: bool = True, inplace: bool = True) tuple[TripletLoops, ndarray[tuple[int, ...], dtype[int64]]] | None#

sort the loops

Parameters:
  • order (str or list of str, optional) –

    By which fields to sort the loops. this argument specifies which fields to compare first, second, etc. Default is ‘pairs’.

    The available options are one or a list of:

    • date:: ‘date1’, ‘date2’, ‘date3’

    • pairs: ‘pairs12’, ‘pairs23’, ‘pairs13’

    • days: ‘days12’, ‘days23’, ‘days13’

    • short name: ‘date’, ‘pairs’, ‘days’. short name will be

      treated as a combination of the above options. For example, ‘date’ is equivalent to [‘date1’, ‘date2’, ‘date3’].

  • ascending (bool, optional) – Whether to sort ascending. Default is True.

  • return_index (bool, optional) – Whether to return the index of the sorted loops. Default is False.

Returns:

  • None or (TripletLoops, np.ndarray). if inplace is True, return the sorted loops

  • and the index of the sorted loops in the original loops. Otherwise,

  • return None.

to_seasons() ndarray[tuple[int, ...], dtype[int8]]#

return the season of each loop.

Returns:

seasons

list of seasons of each loop.

0: not the same season 1: spring 2: summer 3: fall 4: winter

Return type:

list

class faninsar.PairsFactory(dates: Sequence, **kwargs)#

Bases: object

This class is used to generate interferometric pairs for InSAR processing.

__init__(dates: Sequence, **kwargs) None#

initialize the PairGenerator class

Parameters:
  • dates (Sequence) – Sequence object that contains the dates. Can be any object that accepted by pd.to_datetime()

  • date_args (dict, optional) – Keyword arguments passed to pd.to_datetime()

from_interval(max_interval: int = 2, max_day: int = 180) Pairs#

generate interferometric pairs by SAR acquisition interval. SAR acquisition interval is defined as the number of SAR acquisitions between two SAR acquisitions.

For example:

if the SAR acquisition interval is 2, then the interferometric pairs will be generated between SAR acquisitions with interval of 1 and 2. This will be useful to generate interferometric pairs with different temporal baselines.

Parameters:
  • max_interval (int) – max interval between two SAR acquisitions for interferometric pair. interval is defined as the number of SAR acquisitions between two SAR acquisitions.

  • max_day (int) – max day between two SAR acquisitions for interferometric pair

Returns:

pairs

Return type:

Pairs object

linking_winter(winter_start: str = '0101', winter_end: str = '0331', n_per_winter: int = 5, max_winter_interval: int = 1) Pairs#

generate interferometric pairs linking winter in each year. winter is defined by month and day for each year. For example, winter_start=’0101’, winter_end=’0331’ means the winter is from Jan 1 to Mar 31 for each year in the time series. This will be useful to add pairs for completely frozen period across years in permafrost region.

Parameters:
  • winter_start (str) – start and end date for the winter which expressed as month and day with format ‘%m%d’

  • winter_end (str) – start and end date for the winter which expressed as month and day with format ‘%m%d’

  • n_per_winter (int) – how many dates will be used for each winter. Those dates will be selected randomly in each winter. Default is 5

  • max_winter_interval (int) – max interval between winters for interferometric pair. If max_winter_interval=1, hen the interferometric pairs will be generated between neighboring winters.

Returns:

pairs

Return type:

Pairs object

from_period(period_start: str = '0101', period_end: str = '0331', n_per_period: int | None = None, n_primary_period: str | None = None, primary_years: list[int] | None = None) Pairs#

generate interferometric pairs between periods for all years. period is defined by month and day for each year. For example, period_start=’0101’, period_end=’0331’ means the period is from Dec 1 to Mar 31 for each year in the time series. This function will randomly select n_per_period dates in each period and generate interferometric pairs between those dates. This will be useful to mitigate the temporal cumulative bias.

Parameters:
  • period_start (str) – start and end date for the period which expressed as month and day with format ‘%m%d’

  • period_end (str) – start and end date for the period which expressed as month and day with format ‘%m%d’

  • n_per_period (int | None) – how many dates will be used for each period. Those dates will be selected randomly in each period. If None, all dates in the period will be used. Default is None.

  • n_primary_period (int, optional) – how many periods/years used as primary date of ifg. For example, if n_primary_period=2, then the interferometric pairs will be generated between the first two periods and the rest periods. If None, all periods will be used. Default is None.

  • primary_years (list, optional) – years used as primary date of ifg. If None, all years in the time series will be used. Default is None.

Returns:

pairs

Return type:

Pairs object

from_summer_winter(summer_start: str = '0801', summer_end: str = '1001', winter_start: str = '1201', winter_end: str = '0331') Pairs#

generate interferometric pairs between summer and winter in each yea. summer and winter are defined by month and day for each year. For example, summer_start=’0801’, summer_end=’1001’ means the summer is from Aug 1 to Oct 1 for each year in the time series. This will be useful to add pairs for whole thawing and freezing process.

Parameters:
  • summer_start (str) – start and end date for the summer which expressed as month and day with format ‘%m%d’

  • summer_end (str) – start and end date for the summer which expressed as month and day with format ‘%m%d’

  • winter_start (str) – start and end date for the winter which expressed as month and day with format ‘%m%d’

  • winter_end (str) – start and end date for the winter which expressed as month and day with format ‘%m%d’

Return type:

Pairs object