class_docstr: Applies basic post-filtering to a time series of anomaly scores
  
  1. Determine which points are anomalies by comparing the absolute value of
     their anomaly score to ``alm_threshold``
  2. Only fire an alarm when ``min_alm_in_window`` of points (within a window
     of ``alarm_window_minutes`` minutes) are labeled as anomalies.
  3. If there is an alarm, then all alarms for the next ``alm_suppress_minutes``
     minutes will be suppressed.
  
  Return a time series of filtered anomaly scores, where the only non-zero
  values are the anomaly scores which were marked as alarms (and not
  suppressed).
code: def filter(self, time_series: TimeSeries) -> TimeSeries:
      k = time_series.names[0]
      times = time_series.univariates[k].time_stamps
      alarms = np.array(time_series.univariates[k].np_values)
      alarm_idxs = alarms.nonzero()[0].tolist()
  
      filtered = np.zeros(len(alarms))
      for idx in alarm_idxs:
          start = bisect.bisect_left(
              times, times[idx] - self.window_secs
          )
          n_recent_alms = (alarms[start : idx + 1] != 0).sum()
  
          start_sup = bisect.bisect_left(
              times, times[idx] - self.suppress_secs
          )
          suppress = (filtered[start_sup : idx + 1] != 0).sum() > 0
  
          min_alm_in_window = min(self.min_alm_in_window, idx - start)
          if n_recent_alms >= min_alm_in_window and not suppress:
              filtered[idx] = alarms[idx]
  
      return TimeSeries({k: UnivariateTimeSeries(times, filtered)})
  
imports: import bisect
  import logging
  import numpy
  from merlion.evaluate.anomaly import TSADMetric
  from merlion.post_process.base import PostRuleBase
  from merlion.utils import UnivariateTimeSeries, TimeSeries
label_desc: Use image node_id 8 for calling the AggregateAlarms obj's underlying member method code with example usage: obj.filter(time_series) and returns: TimeSeries