def dating(
    input_video,
    timelist,
    mintrack=3,
    cell_list=None,
    label_list=None,
    start=0,
    minref=35,
    maxref=48,
    mindiff=6,
    minsize=50,
    minmax=41,
    mindis=10,
    dyn_thresh=False,
    match_frac=0.4,
    split_frac=0.1,
    merge_frac=0.1,
    output_splits_merges=False,
):
    """
    This function performs the thunderstorm detection and tracking DATing.
    It requires a 3-D input array that contains the temporal succession of the 2-D data
    array of each timestep. On each timestep the detection is performed, the identified
    objects are advected with a flow prediction and the advected objects are matched to
    the newly identified objects of the next timestep.
    The last portion re-arranges the data into tracks sorted by ID-number.

    Parameters
    ----------
    input_video: array-like
        Array of shape (t,m,n) containing input image, with t being the temporal
        dimension and m,n the spatial dimensions. Thresholds are tuned to maximum
        reflectivity in dBZ with a spatial resolution of 1 km and a temporal resolution
        of 5 min. Nan values are ignored.
    timelist: list
        List of length t containing string of time and date of each (m,n) field.
    mintrack: int, optional
        minimum duration of cell-track to be counted. The default is 3 time steps.
    cell_list: list or None, optional
        If you wish to expand an existing list of cells, insert previous cell-list here.
        The default is None.
        If not None, requires that label_list has the same length.
    label_list: list or None, optional
        If you wish to expand an existing list of cells, insert previous label-list here.
        The default is None.
        If not None, requires that cell_list has the same length.
    start: int, optional
        If you wish to expand an existing list of cells, the input video must contain 2
        timesteps prior to the merging. The start can then be set to 2, allowing the
        motion vectors to be formed from the first three grids and continuing the cell
        tracking from there. The default is 0, which initiates a new tracking sequence.
    minref: float, optional
        Lower threshold for object detection. Lower values will be set to NaN.
        The default is 35 dBZ.
    maxref: float, optional
        Upper threshold for object detection. Higher values will be set to this value.
        The default is 48 dBZ.
    mindiff: float, optional
        Minimal difference between two identified maxima within same area to split area
        into two objects. The default is 6 dBZ.
    minsize: float, optional
        Minimal area for possible detected object. The default is 50 pixels.
    minmax: float, optional
        Minimum value of maximum in identified objects. Objects with a maximum lower
        than this will be discarded. The default is 41 dBZ.
    mindis: float, optional
        Minimum distance between two maxima of identified objects. Objects with a
        smaller distance will be merged. The default is 10 km.
    match_frac: float, optional
        Minimum overlap fraction between two objects to be considered the same object.
        Default is 0.4.
    split_frac: float, optional
        Minimum overlap fraction between two objects for the object at second timestep
        to be considered possibly split from the object at the first timestep.
        Default is 0.1.
    merge_frac: float, optional
        Minimum overlap fraction between two objects for the object at second timestep
        to be considered possibly merged from the object at the first timestep.
        Default is 0.1.
    output_splits_merges: bool, optional
        If True, the output will contain information about splits and merges.
        The provided columns are:

        .. tabularcolumns:: |p{2cm}|L|

        +-------------------+--------------------------------------------------------------+
        | Attribute         | Description                                                  |
        +===================+==============================================================+
        | splitted          | Indicates if the cell is considered split into multiple cells|
        +-------------------+--------------------------------------------------------------+
        | split_IDs         | List of IDs at the next timestep that the cell split into    |
        +-------------------+--------------------------------------------------------------+
        | merged            | Indicates if the cell is considered a merge of multiple cells|
        +-------------------+--------------------------------------------------------------+
        | merged_IDs        | List of IDs from the previous timestep that merged into this |
        |                   | cell                                                         |
        +-------------------+--------------------------------------------------------------+
        | results_from_split| True if the cell is a result of a split (i.e., the ID of the |
        |                   | cell is present in the split_IDs of some cell at the previous|
        |                   | timestep)                                                    |
        +-------------------+--------------------------------------------------------------+
        | will_merge        | True if the cell will merge at the next timestep (i.e., the  |
        |                   | ID of the cell is present in the merge_IDs of some cell at   |
        |                   | the next timestep; empty if the next timestep is not tracked)|
        +-------------------+--------------------------------------------------------------+

    Returns
    -------
    track_list: list of dataframes
        Each dataframe contains the track and properties belonging to one cell ID.
        Columns of dataframes: ID - cell ID, time - time stamp, x - array of all
        x-coordinates of cell, y -  array of all y-coordinates of cell, cen_x -
        x-coordinate of cell centroid, cen_y - y-coordinate of cell centroid, max_ref -
        maximum (reflectivity) value of cell, cont - cell contours
    cell_list: list of dataframes
        Each dataframe contains the detected cells and properties belonging to one
        timestep. The IDs are already matched to provide a track.
        Columns of dataframes: ID - cell ID, time - time stamp, x - array of all
        x-coordinates of cell, y -  array of all y-coordinates of cell, cen_x -
        x-coordinate of cell centroid, cen_y - y-coordinate of cell centroid, max_ref -
        maximum (reflectivity) value of cell, cont - cell contours
    label_list: list of arrays
        Each (n,m) array contains the gridded IDs of the cells identified in the
        corresponding timestep. The IDs are already matched to provide a track.

    """
    if not SKIMAGE_IMPORTED:
        raise MissingOptionalDependency(
            "skimage is required for thunderstorm DATing " "but it is not installed"
        )
    if not PANDAS_IMPORTED:
        raise MissingOptionalDependency(
            "pandas is required for thunderstorm DATing " "but it is not installed"
        )

    # Check arguments
    if cell_list is None or label_list is None:
        cell_list = []
        label_list = []
    else:
        if not len(cell_list) == len(label_list):
            raise ValueError("len(cell_list) != len(label_list)")
    if start > len(timelist):
        raise ValueError("start > len(timelist)")

    oflow_method = motion.get_method("LK")
    if len(label_list) == 0:
        max_ID = 0
    else:
        max_ID = np.nanmax([np.nanmax(np.unique(label_list)), 0])
    for t in range(start, len(timelist)):
        cells_id, labels = tstorm_detect.detection(
            input_video[t, :, :],
            minref=minref,
            maxref=maxref,
            mindiff=mindiff,
            minsize=minsize,
            minmax=minmax,
            mindis=mindis,
            time=timelist[t],
            output_splits_merges=output_splits_merges,
        )
        if len(cell_list) < 2:
            cell_list.append(cells_id)
            label_list.append(labels)
            cid = np.unique(labels)
            max_ID = np.nanmax([np.nanmax(cid), max_ID]) + 1
            continue
        if t >= 2:
            flowfield = oflow_method(input_video[t - 2 : t + 1, :, :])
            cells_id, max_ID, newlabels, splitted_cells = tracking(
                cells_id,
                cell_list[-1],
                labels,
                flowfield,
                max_ID,
                match_frac=match_frac,
                split_frac=split_frac,
                merge_frac=merge_frac,
                output_splits_merges=output_splits_merges,
            )

            if output_splits_merges:
                # Assign splitted parameters for the previous timestep
                for _, split_cell in splitted_cells.iterrows():
                    prev_list_id = cell_list[-1][
                        cell_list[-1].ID == split_cell.ID
                    ].index.item()

                    split_ids = split_cell.split_IDs
                    split_ids_updated = []
                    for sid in split_ids:
                        split_ids_updated.append(newlabels[labels == sid][0])

                    cell_list[-1].at[prev_list_id, "splitted"] = True
                    cell_list[-1].at[prev_list_id, "split_IDs"] = split_ids_updated

                    for sid in split_ids_updated:
                        cur_list_id = cells_id[cells_id.ID == sid].index.item()
                        cells_id.at[cur_list_id, "results_from_split"] = True

                merged_cells = cells_id[cells_id.merged == True]
                for _, cell in merged_cells.iterrows():
                    for merged_id in cell.merged_IDs:
                        prev_list_id = cell_list[-1][
                            cell_list[-1].ID == merged_id
                        ].index.item()
                        cell_list[-1].at[prev_list_id, "will_merge"] = True

            cid = np.unique(newlabels)
            # max_ID = np.nanmax([np.nanmax(cid), max_ID])
            cell_list.append(cells_id)
            label_list.append(newlabels)

    track_list = couple_track(cell_list[2:], int(max_ID), mintrack)

    return track_list, cell_list, label_list
This function performs the thunderstorm detection and tracking DATing.
It requires a 3-D input array that contains the temporal succession of the 2-D data
array of each timestep. On each timestep the detection is performed, the identified
objects are advected with a flow prediction and the advected objects are matched to
the newly identified objects of the next timestep.
The last portion re-arranges the data into tracks sorted by ID-number.

Parameters
----------
input_video: array-like
Array of shape (t,m,n) containing input image, with t being the temporal
dimension and m,n the spatial dimensions. Thresholds are tuned to maximum
reflectivity in dBZ with a spatial resolution of 1 km and a temporal resolution
of 5 min. Nan values are ignored.
timelist: list
List of length t containing string of time and date of each (m,n) field.
mintrack: int, optional
minimum duration of cell-track to be counted. The default is 3 time steps.
cell_list: list or None, optional
If you wish to expand an existing list of cells, insert previous cell-list here.
The default is None.
If not None, requires that label_list has the same length.
label_list: list or None, optional
If you wish to expand an existing list of cells, insert previous label-list here.
The default is None.
If not None, requires that cell_list has the same length.
start: int, optional
If you wish to expand an existing list of cells, the input video must contain 2
timesteps prior to the merging. The start can then be set to 2, allowing the
motion vectors to be formed from the first three grids and continuing the cell
tracking from there. The default is 0, which initiates a new tracking sequence.
minref: float, optional
Lower threshold for object detection. Lower values will be set to NaN.
The default is 35 dBZ.
maxref: float, optional
Upper threshold for object detection. Higher values will be set to this value.
The default is 48 dBZ.
mindiff: float, optional
Minimal difference between two identified maxima within same area to split area
into two objects. The default is 6 dBZ.
minsize: float, optional
Minimal area for possible detected object. The default is 50 pixels.
minmax: float, optional
Minimum value of maximum in identified objects. Objects with a maximum lower
than this will be discarded. The default is 41 dBZ.
mindis: float, optional
Minimum distance between two maxima of identified objects. Objects with a
smaller distance will be merged. The default is 10 km.
match_frac: float, optional
Minimum overlap fraction between two objects to be considered the same object.
Default is 0.4.
split_frac: float, optional
Minimum overlap fraction between two objects for the object at second timestep
to be considered possibly split from the object at the first timestep.
Default is 0.1.
merge_frac: float, optional
Minimum overlap fraction between two objects for the object at second timestep
to be considered possibly merged from the object at the first timestep.
Default is 0.1.
output_splits_merges: bool, optional
If True, the output will contain information about splits and merges.
The provided columns are:

.. tabularcolumns:: |p{2cm}|L|

+-------------------+--------------------------------------------------------------+
| Attribute         | Description                                                  |
+===================+==============================================================+
| splitted          | Indicates if the cell is considered split into multiple cells|
+-------------------+--------------------------------------------------------------+
| split_IDs         | List of IDs at the next timestep that the cell split into    |
+-------------------+--------------------------------------------------------------+
| merged            | Indicates if the cell is considered a merge of multiple cells|
+-------------------+--------------------------------------------------------------+
| merged_IDs        | List of IDs from the previous timestep that merged into this |
|                   | cell                                                         |
+-------------------+--------------------------------------------------------------+
| results_from_split| True if the cell is a result of a split (i.e., the ID of the |
|                   | cell is present in the split_IDs of some cell at the previous|
|                   | timestep)                                                    |
+-------------------+--------------------------------------------------------------+
| will_merge        | True if the cell will merge at the next timestep (i.e., the  |
|                   | ID of the cell is present in the merge_IDs of some cell at   |
|                   | the next timestep; empty if the next timestep is not tracked)|
+-------------------+--------------------------------------------------------------+

Returns
-------
track_list: list of dataframes
Each dataframe contains the track and properties belonging to one cell ID.
Columns of dataframes: ID - cell ID, time - time stamp, x - array of all
x-coordinates of cell, y -  array of all y-coordinates of cell, cen_x -
x-coordinate of cell centroid, cen_y - y-coordinate of cell centroid, max_ref -
maximum (reflectivity) value of cell, cont - cell contours
cell_list: list of dataframes
Each dataframe contains the detected cells and properties belonging to one
timestep. The IDs are already matched to provide a track.
Columns of dataframes: ID - cell ID, time - time stamp, x - array of all
x-coordinates of cell, y -  array of all y-coordinates of cell, cen_x -
x-coordinate of cell centroid, cen_y - y-coordinate of cell centroid, max_ref -
maximum (reflectivity) value of cell, cont - cell contours
label_list: list of arrays
Each (n,m) array contains the gridded IDs of the cells identified in the
corresponding timestep. The IDs are already matched to provide a track.
pysteps/tracking/tdating.py