code: def validate_events(
      event_list: List[
          Union[Tuple[pd.Timestamp, pd.Timestamp], pd.Timestamp]
      ],
      point_as_interval: bool = False,
  ) -> List[Union[Tuple[pd.Timestamp, pd.Timestamp], pd.Timestamp]]:
      """Validate event list.
  
      This function will check and fix some common issues in an event list (a
      list of time windows), including invalid time window, overlapped time
      windows, unsorted events, etc.
  
      Parameters
      ----------
      event_list: list
          A list of events, where an event is a pandas Timestamp if it is
          instantaneous or a 2-tuple of pandas Timestamps if it is a closed time
          interval.
  
      point_as_interval: bool, optional
          Whether to return all instantaneous event as a close interval with
          identicial start point and end point. Default: False.
  
      Returns
      -------
      list:
          A validated list of events.
  
      """
      if not isinstance(event_list, list):
          raise TypeError("Argument `event_list` must be a list.")
      for event in event_list:
          if not (
              isinstance(event, pd.Timestamp)
              or (
                  isinstance(event, tuple)
                  and (len(event) == 2)
                  and all(
                      [
                          isinstance(event[i], pd.Timestamp)
                          for i in [0, 1]
                      ]
                  )
              )
          ):
              raise TypeError(
                  "Every event in the list must be a pandas Timestamp, "
                  "or a 2-tuple of Timestamps."
              )
  
      time_window_ends = []  # type: List[pd.Timestamp]
      time_window_type = []  # type: List[int]
      for time_window in event_list:
          if isinstance(time_window, tuple):
              if time_window[0] <= time_window[1]:
                  time_window_ends.append(time_window[0])
                  time_window_type.append(+1)
                  time_window_ends.append(time_window[1])
                  time_window_type.append(-1)
          else:
              time_window_ends.append(time_window)
              time_window_type.append(+1)
              time_window_ends.append(time_window)
              time_window_type.append(-1)
      time_window_end_series = pd.Series(
          time_window_type,
          index=pd.DatetimeIndex(time_window_ends),
          dtype=int,
      )  # type: pd.Series
      time_window_end_series.sort_index(kind="mergesort", inplace=True)
      time_window_end_series = time_window_end_series.cumsum()
      status = 0
      merged_event_list = (
          []
      )  # type: List[Union[Tuple[pd.Timestamp, pd.Timestamp], pd.Timestamp]]
      for (
          t,
          v,
      ) in (
          time_window_end_series.iteritems()
      ):  # type: pd.Timestamp, int
          if (status == 0) and (v > 0):
              start = t  # type: pd.Timestamp
              status = 1
          if (status == 1) and (v <= 0):
              end = t  # type: pd.Timestamp
              merged_event_list.append([start, end])
              status = 0
      for i in range(1, len(merged_event_list)):
          this_start = merged_event_list[i][0]  # type: pd.Timestamp
          this_end = merged_event_list[i][1]  # type: pd.Timestamp
          last_start = merged_event_list[i - 1][0]  # type: pd.Timestamp
          last_end = merged_event_list[i - 1][1]  # type: pd.Timestamp
          if last_end + pd.Timedelta("1ns") >= this_start:
              merged_event_list[i] = [last_start, this_end]
              merged_event_list[i - 1] = None
      merged_event_list = [
          w[0] if (w[0] == w[1] and not point_as_interval) else tuple(w)
          for w in merged_event_list
          if w is not None
      ]
      return merged_event_list
  
file_path: adtk/src/adtk/data/_data.py
imports: from typing import Dict, List, Optional, Tuple, Union, overload
  import numpy
  import pandas
label_desc: Use image node_id 2 for calling a global function with example usage: validate_events(event_list, point_as_interval) and returns: merged_event_list